blob: a966ab544f826408f4f6a86ee1534d16c5fea849 [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
initial.commit586acc5fe2008-07-26 22:42:52137//-----------------------------------------------------------------------------
138
ttuttle859dc7a2015-04-23 19:42:29139namespace net {
140
[email protected]13c8a092010-07-29 06:15:44141namespace {
142
[email protected]42cba2fb2013-03-29 19:58:57143const base::string16 kBar(ASCIIToUTF16("bar"));
144const base::string16 kBar2(ASCIIToUTF16("bar2"));
145const base::string16 kBar3(ASCIIToUTF16("bar3"));
146const base::string16 kBaz(ASCIIToUTF16("baz"));
147const base::string16 kFirst(ASCIIToUTF16("first"));
148const base::string16 kFoo(ASCIIToUTF16("foo"));
149const base::string16 kFoo2(ASCIIToUTF16("foo2"));
150const base::string16 kFoo3(ASCIIToUTF16("foo3"));
151const base::string16 kFou(ASCIIToUTF16("fou"));
152const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57153const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44154
bnc2df4b522016-07-08 18:17:43155const char kAlternativeServiceHttpHeader[] =
156 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
157
ttuttle859dc7a2015-04-23 19:42:29158int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
Matt Menked23ab952019-03-06 00:24:40159 return session
160 ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
161 ProxyServer::Direct())
ttuttle859dc7a2015-04-23 19:42:29162 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02163}
164
ttuttle859dc7a2015-04-23 19:42:29165bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
Matt Menked23ab952019-03-06 00:24:40166 return session
167 ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
168 ProxyServer::Direct())
ttuttle859dc7a2015-04-23 19:42:29169 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52170}
171
[email protected]f3da152d2012-06-02 01:00:57172// Takes in a Value created from a NetLogHttpResponseParameter, and returns
173// a JSONified list of headers as a single string. Uses single quotes instead
174// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27175bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57176 if (!params)
177 return false;
[email protected]ea5ef4c2013-06-13 22:50:27178 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57179 if (!params->GetList("headers", &header_list))
180 return false;
181 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34182 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28183 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57184 return true;
185}
186
[email protected]029c83b62013-01-24 05:28:20187// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
188// used.
ttuttle859dc7a2015-04-23 19:42:29189void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20190 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19191 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25192
[email protected]029c83b62013-01-24 05:28:20193 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
194 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
195
ttuttle859dc7a2015-04-23 19:42:29196 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20197 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25198
199 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25200
[email protected]3b23a222013-05-15 21:33:25201 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25202 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
203 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25204 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25205}
206
[email protected]029c83b62013-01-24 05:28:20207// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
208// used.
ttuttle859dc7a2015-04-23 19:42:29209void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25210 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20211 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19212 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20213
214 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
215 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
216
ttuttle859dc7a2015-04-23 19:42:29217 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
218 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20219 EXPECT_LE(load_timing_info.connect_timing.connect_end,
220 load_timing_info.send_start);
221
222 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20223
[email protected]3b23a222013-05-15 21:33:25224 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20225 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
226 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25227 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20228}
229
230// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
231// used.
ttuttle859dc7a2015-04-23 19:42:29232void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20233 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19234 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20235
ttuttle859dc7a2015-04-23 19:42:29236 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20237
238 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
239 EXPECT_LE(load_timing_info.proxy_resolve_start,
240 load_timing_info.proxy_resolve_end);
241 EXPECT_LE(load_timing_info.proxy_resolve_end,
242 load_timing_info.send_start);
243 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20244
[email protected]3b23a222013-05-15 21:33:25245 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20246 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
247 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25248 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20249}
250
251// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
252// used.
ttuttle859dc7a2015-04-23 19:42:29253void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20254 int connect_timing_flags) {
255 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19256 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20257
258 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
259 EXPECT_LE(load_timing_info.proxy_resolve_start,
260 load_timing_info.proxy_resolve_end);
261 EXPECT_LE(load_timing_info.proxy_resolve_end,
262 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29263 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
264 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20265 EXPECT_LE(load_timing_info.connect_timing.connect_end,
266 load_timing_info.send_start);
267
268 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20269
[email protected]3b23a222013-05-15 21:33:25270 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20271 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
272 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25273 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25274}
275
Matt Menke2436b2f2018-12-11 18:07:11276// ProxyResolver that records URLs passed to it, and that can be told what
277// result to return.
278class CapturingProxyResolver : public ProxyResolver {
279 public:
280 CapturingProxyResolver()
281 : proxy_server_(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 80)) {}
282 ~CapturingProxyResolver() override = default;
283
284 int GetProxyForURL(const GURL& url,
285 ProxyInfo* results,
286 CompletionOnceCallback callback,
287 std::unique_ptr<Request>* request,
288 const NetLogWithSource& net_log) override {
289 results->UseProxyServer(proxy_server_);
290 resolved_.push_back(url);
291 return OK;
292 }
293
294 // Sets whether the resolver should use direct connections, instead of a
295 // proxy.
296 void set_proxy_server(ProxyServer proxy_server) {
297 proxy_server_ = proxy_server;
298 }
299
300 const std::vector<GURL>& resolved() const { return resolved_; }
301
302 private:
303 std::vector<GURL> resolved_;
304
305 ProxyServer proxy_server_;
306
307 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
308};
309
310class CapturingProxyResolverFactory : public ProxyResolverFactory {
311 public:
312 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
313 : ProxyResolverFactory(false), resolver_(resolver) {}
314
315 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
316 std::unique_ptr<ProxyResolver>* resolver,
317 CompletionOnceCallback callback,
318 std::unique_ptr<Request>* request) override {
319 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
320 return OK;
321 }
322
323 private:
324 ProxyResolver* resolver_;
325};
326
danakj1fd259a02016-04-16 03:17:09327std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42328 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34329 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14330}
331
xunjieli96f2a402017-06-05 17:24:27332class FailingProxyResolverFactory : public ProxyResolverFactory {
333 public:
334 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
335
336 // ProxyResolverFactory override.
Lily Houghton99597862018-03-07 16:40:42337 int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
338 std::unique_ptr<ProxyResolver>* result,
Bence Békycc5b88a2018-05-25 20:24:17339 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:42340 std::unique_ptr<Request>* request) override {
xunjieli96f2a402017-06-05 17:24:27341 return ERR_PAC_SCRIPT_FAILED;
342 }
343};
344
David Benjamin5cb91132018-04-06 05:54:49345class TestSSLConfigService : public SSLConfigService {
346 public:
347 explicit TestSSLConfigService(const SSLConfig& config) : config_(config) {}
Ryan Sleevib8449e02018-07-15 04:31:07348 ~TestSSLConfigService() override = default;
David Benjamin5cb91132018-04-06 05:54:49349
350 void GetSSLConfig(SSLConfig* config) override { *config = config_; }
351
Nick Harper89bc7212018-07-31 19:07:57352 bool CanShareConnectionWithClientCerts(
353 const std::string& hostname) const override {
354 return false;
355 }
356
David Benjamin5cb91132018-04-06 05:54:49357 private:
David Benjamin5cb91132018-04-06 05:54:49358 SSLConfig config_;
359};
360
[email protected]448d4ca52012-03-04 04:12:23361} // namespace
362
Bence Béky98447b12018-05-08 03:14:01363class HttpNetworkTransactionTest : public PlatformTest,
364 public WithScopedTaskEnvironment {
[email protected]483fa202013-05-14 01:07:03365 public:
bncd16676a2016-07-20 16:23:01366 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03367 // Important to restore the per-pool limit first, since the pool limit must
368 // always be greater than group limit, and the tests reduce both limits.
369 ClientSocketPoolManager::set_max_sockets_per_pool(
370 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
371 ClientSocketPoolManager::set_max_sockets_per_group(
372 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
373 }
374
[email protected]e3ceb682011-06-28 23:55:46375 protected:
[email protected]23e482282013-06-14 16:08:02376 HttpNetworkTransactionTest()
Andrew Comminos517a92c2019-01-14 17:49:56377 : WithScopedTaskEnvironment(
378 base::test::ScopedTaskEnvironment::MainThreadType::IO_MOCK_TIME,
379 base::test::ScopedTaskEnvironment::NowSource::
380 MAIN_THREAD_MOCK_TIME),
Matt Menked6fd2a52019-03-20 06:14:36381 dummy_connect_job_params_(
382 nullptr /* client_socket_factory */,
383 nullptr /* host_resolver */,
Matt Menkeb88837e2019-03-20 11:50:40384 nullptr /* http_auth_cache */,
385 nullptr /* http_auth_handler_factory */,
386 nullptr /* spdy_session_pool */,
Matt Menkeb5fb42b2019-03-22 17:26:13387 nullptr /* quic_supported_versions */,
Matt Menkeb88837e2019-03-20 11:50:40388 nullptr /* quic_stream_factory */,
Matt Menked6fd2a52019-03-20 06:14:36389 nullptr /* proxy_delegate */,
390 nullptr /* http_user_agent_settings */,
391 SSLClientSocketContext(),
392 SSLClientSocketContext(),
393 nullptr /* socket_performance_watcher_factory */,
394 nullptr /* network_quality_estimator */,
395 nullptr /* net_log */,
396 nullptr /* websocket_endpoint_lock_manager */),
Andrew Comminos517a92c2019-01-14 17:49:56397 ssl_(ASYNC, OK),
bnc032658ba2016-09-26 18:17:15398 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03399 HttpNetworkSession::NORMAL_SOCKET_POOL)),
400 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
401 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28402 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03403 }
[email protected]bb88e1d32013-05-03 23:11:07404
[email protected]e3ceb682011-06-28 23:55:46405 struct SimpleGetHelperResult {
406 int rv;
407 std::string status_line;
408 std::string response_data;
sclittlefb249892015-09-10 21:33:22409 int64_t total_received_bytes;
410 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25411 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47412 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59413 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46414 };
415
dcheng67be2b1f2014-10-27 21:47:29416 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50417 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55418 base::RunLoop().RunUntilIdle();
Andrew Comminos517a92c2019-01-14 17:49:56419 // Set an initial delay to ensure that the first call to TimeTicks::Now()
420 // before incrementing the counter does not return a null value.
421 FastForwardBy(TimeDelta::FromSeconds(1));
[email protected]2ff8b312010-04-26 22:20:54422 }
423
dcheng67be2b1f2014-10-27 21:47:29424 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50425 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55426 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09427 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55428 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09429 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50430 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55431 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09432 }
433
Andrew Comminos1f2ff1cc2018-12-14 05:22:38434 void Check100ResponseTiming(bool use_spdy);
435
[email protected]202965992011-12-07 23:04:51436 // Either |write_failure| specifies a write failure or |read_failure|
437 // specifies a read failure when using a reused socket. In either case, the
438 // failure should cause the network transaction to resend the request, and the
439 // other argument should be NULL.
440 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
441 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52442
[email protected]a34f61ee2014-03-18 20:59:49443 // Either |write_failure| specifies a write failure or |read_failure|
444 // specifies a read failure when using a reused socket. In either case, the
445 // failure should cause the network transaction to resend the request, and the
446 // other argument should be NULL.
447 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10448 const MockRead* read_failure,
449 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49450
Ryan Sleevib8d7ea02018-05-07 20:01:01451 SimpleGetHelperResult SimpleGetHelperForData(
452 base::span<StaticSocketDataProvider*> providers) {
[email protected]ff007e162009-05-23 09:13:15453 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52454
[email protected]ff007e162009-05-23 09:13:15455 HttpRequestInfo request;
456 request.method = "GET";
bncce36dca22015-04-21 22:11:23457 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10458 request.traffic_annotation =
459 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52460
vishal.b62985ca92015-04-17 08:45:51461 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07462 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09463 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16464 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27465
Ryan Sleevib8d7ea02018-05-07 20:01:01466 for (auto* provider : providers) {
467 session_deps_.socket_factory->AddSocketDataProvider(provider);
[email protected]5a60c8b2011-10-19 20:14:29468 }
initial.commit586acc5fe2008-07-26 22:42:52469
[email protected]49639fa2011-12-20 23:22:41470 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52471
eroman24bc6a12015-05-06 19:55:48472 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16473 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01474 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52475
[email protected]ff007e162009-05-23 09:13:15476 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16477 out.total_received_bytes = trans.GetTotalReceivedBytes();
478 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25479
480 // Even in the failure cases that use this function, connections are always
481 // successfully established before the error.
bnc691fda62016-08-12 00:43:16482 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25483 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
484
[email protected]ff007e162009-05-23 09:13:15485 if (out.rv != OK)
486 return out;
487
bnc691fda62016-08-12 00:43:16488 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50489 // Can't use ASSERT_* inside helper functions like this, so
490 // return an error.
wezca1070932016-05-26 20:30:52491 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50492 out.rv = ERR_UNEXPECTED;
493 return out;
494 }
[email protected]ff007e162009-05-23 09:13:15495 out.status_line = response->headers->GetStatusLine();
496
Tsuyoshi Horo01faed62019-02-20 22:11:37497 EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
498 EXPECT_EQ(80, response->remote_endpoint.port());
[email protected]6d81b482011-02-22 19:47:19499
ttuttled9dbc652015-09-29 20:00:59500 bool got_endpoint =
bnc691fda62016-08-12 00:43:16501 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59502 EXPECT_EQ(got_endpoint,
503 out.remote_endpoint_after_start.address().size() > 0);
504
bnc691fda62016-08-12 00:43:16505 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01506 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40507
mmenke43758e62015-05-04 21:09:46508 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40509 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39510 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00511 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
512 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39513 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00514 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
515 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15516
[email protected]f3da152d2012-06-02 01:00:57517 std::string line;
518 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
519 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
520
[email protected]79e1fd62013-06-20 06:50:04521 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16522 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04523 std::string value;
524 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23525 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04526 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
527 EXPECT_EQ("keep-alive", value);
528
529 std::string response_headers;
530 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23531 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04532 response_headers);
[email protected]3deb9a52010-11-11 00:24:40533
bnc691fda62016-08-12 00:43:16534 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22535 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16536 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22537
bnc691fda62016-08-12 00:43:16538 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47539 return out;
[email protected]ff007e162009-05-23 09:13:15540 }
initial.commit586acc5fe2008-07-26 22:42:52541
Ryan Sleevib8d7ea02018-05-07 20:01:01542 SimpleGetHelperResult SimpleGetHelper(base::span<const MockRead> data_reads) {
sclittlefb249892015-09-10 21:33:22543 MockWrite data_writes[] = {
544 MockWrite("GET / HTTP/1.1\r\n"
545 "Host: www.example.org\r\n"
546 "Connection: keep-alive\r\n\r\n"),
547 };
[email protected]5a60c8b2011-10-19 20:14:29548
Ryan Sleevib8d7ea02018-05-07 20:01:01549 StaticSocketDataProvider reads(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:22550 StaticSocketDataProvider* data[] = {&reads};
Ryan Sleevib8d7ea02018-05-07 20:01:01551 SimpleGetHelperResult out = SimpleGetHelperForData(data);
sclittlefb249892015-09-10 21:33:22552
Ryan Sleevib8d7ea02018-05-07 20:01:01553 EXPECT_EQ(CountWriteBytes(data_writes), out.total_sent_bytes);
sclittlefb249892015-09-10 21:33:22554 return out;
[email protected]b8015c42013-12-24 15:18:19555 }
556
bnc032658ba2016-09-26 18:17:15557 void AddSSLSocketData() {
558 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49559 ssl_.ssl_info.cert =
560 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
561 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15562 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
563 }
564
[email protected]ff007e162009-05-23 09:13:15565 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
566 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52567
[email protected]ff007e162009-05-23 09:13:15568 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07569
[email protected]bb88e1d32013-05-03 23:11:07570 void CheckErrorIsPassedBack(int error, IoMode mode);
571
Matt Menked6fd2a52019-03-20 06:14:36572 const CommonConnectJobParams dummy_connect_job_params_;
573
Douglas Creager134b52e2018-11-09 18:00:14574 // These clocks are defined here, even though they're only used in the
575 // Reporting tests below, since they need to be destroyed after
576 // |session_deps_|.
577 base::SimpleTestClock clock_;
578 base::SimpleTestTickClock tick_clock_;
579
[email protected]4bd46222013-05-14 19:32:23580 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07581 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15582 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03583
584 // Original socket limits. Some tests set these. Safest to always restore
585 // them once each test has been run.
586 int old_max_group_sockets_;
587 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15588};
[email protected]231d5a32008-09-13 00:45:27589
[email protected]448d4ca52012-03-04 04:12:23590namespace {
591
ryansturm49a8cb12016-06-15 16:51:09592class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27593 public:
ryansturm49a8cb12016-06-15 16:51:09594 BeforeHeadersSentHandler()
595 : observed_before_headers_sent_with_proxy_(false),
596 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27597
ryansturm49a8cb12016-06-15 16:51:09598 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
599 HttpRequestHeaders* request_headers) {
600 observed_before_headers_sent_ = true;
601 if (!proxy_info.is_http() && !proxy_info.is_https() &&
602 !proxy_info.is_quic()) {
603 return;
604 }
605 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27606 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
607 }
608
ryansturm49a8cb12016-06-15 16:51:09609 bool observed_before_headers_sent_with_proxy() const {
610 return observed_before_headers_sent_with_proxy_;
611 }
612
613 bool observed_before_headers_sent() const {
614 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27615 }
616
617 std::string observed_proxy_server_uri() const {
618 return observed_proxy_server_uri_;
619 }
620
621 private:
ryansturm49a8cb12016-06-15 16:51:09622 bool observed_before_headers_sent_with_proxy_;
623 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27624 std::string observed_proxy_server_uri_;
625
ryansturm49a8cb12016-06-15 16:51:09626 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27627};
628
[email protected]15a5ccf82008-10-23 19:57:43629// Fill |str| with a long header list that consumes >= |size| bytes.
630void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51631 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19632 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
633 const int sizeof_row = strlen(row);
634 const int num_rows = static_cast<int>(
635 ceil(static_cast<float>(size) / sizeof_row));
636 const int sizeof_data = num_rows * sizeof_row;
637 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43638 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51639
[email protected]4ddaf2502008-10-23 18:26:19640 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43641 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19642}
643
thakis84dff942015-07-28 20:47:38644#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09645uint64_t MockGetMSTime() {
646 // Tue, 23 May 2017 20:13:07 +0000
647 return 131400439870000000;
648}
649
[email protected]385a4672009-03-11 22:21:29650// Alternative functions that eliminate randomness and dependency on the local
651// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37652void MockGenerateRandom(uint8_t* output, size_t n) {
653 // This is set to 0xaa because the client challenge for testing in
654 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
655 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29656}
657
[email protected]fe2bc6a2009-03-23 16:52:20658std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37659 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29660}
thakis84dff942015-07-28 20:47:38661#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29662
Matt Menked6fd2a52019-03-20 06:14:36663class CaptureGroupIdTransportSocketPool : public TransportClientSocketPool {
[email protected]04e5be32009-06-26 20:00:31664 public:
Matt Menked6fd2a52019-03-20 06:14:36665 explicit CaptureGroupIdTransportSocketPool(
666 const CommonConnectJobParams* common_connect_job_params)
667 : TransportClientSocketPool(0,
668 0,
669 base::TimeDelta(),
Matt Menkeaafff542019-04-22 22:09:36670 ProxyServer::Direct(),
671 false /* is_for_websockets */,
Matt Menked6fd2a52019-03-20 06:14:36672 common_connect_job_params,
673 nullptr /* ssl_config_service */) {}
[email protected]e60e47a2010-07-14 03:37:18674
Matt Menkef6edce752019-03-19 17:21:56675 const ClientSocketPool::GroupId& last_group_id_received() const {
676 return last_group_id_;
[email protected]d80a4322009-08-14 07:07:49677 }
678
Tarun Bansal162eabe52018-01-20 01:16:39679 bool socket_requested() const { return socket_requested_; }
680
Matt Menke28ac03e2019-02-25 22:25:50681 int RequestSocket(
Matt Menkef6edce752019-03-19 17:21:56682 const ClientSocketPool::GroupId& group_id,
Matt Menkebd12b7e2019-03-25 21:12:03683 scoped_refptr<ClientSocketPool::SocketParams> socket_params,
Matt Menke28ac03e2019-02-25 22:25:50684 RequestPriority priority,
685 const SocketTag& socket_tag,
686 ClientSocketPool::RespectLimits respect_limits,
687 ClientSocketHandle* handle,
688 CompletionOnceCallback callback,
689 const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback,
690 const NetLogWithSource& net_log) override {
Matt Menkef6edce752019-03-19 17:21:56691 last_group_id_ = group_id;
Tarun Bansal162eabe52018-01-20 01:16:39692 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31693 return ERR_IO_PENDING;
694 }
Matt Menkef6edce752019-03-19 17:21:56695 void CancelRequest(const ClientSocketPool::GroupId& group_id,
dmichaeld6e570d2014-12-18 22:30:57696 ClientSocketHandle* handle) override {}
Matt Menkef6edce752019-03-19 17:21:56697 void ReleaseSocket(const ClientSocketPool::GroupId& group_id,
danakj1fd259a02016-04-16 03:17:09698 std::unique_ptr<StreamSocket> socket,
Matt Menkebf3c767d2019-04-15 23:28:24699 int64_t generation) override {}
dmichaeld6e570d2014-12-18 22:30:57700 void CloseIdleSockets() override {}
Matt Menkef6edce752019-03-19 17:21:56701 void CloseIdleSocketsInGroup(
702 const ClientSocketPool::GroupId& group_id) override {}
dmichaeld6e570d2014-12-18 22:30:57703 int IdleSocketCount() const override { return 0; }
Matt Menkef6edce752019-03-19 17:21:56704 size_t IdleSocketCountInGroup(
705 const ClientSocketPool::GroupId& group_id) const override {
[email protected]04e5be32009-06-26 20:00:31706 return 0;
707 }
Matt Menkef6edce752019-03-19 17:21:56708 LoadState GetLoadState(const ClientSocketPool::GroupId& group_id,
dmichaeld6e570d2014-12-18 22:30:57709 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31710 return LOAD_STATE_IDLE;
711 }
[email protected]d80a4322009-08-14 07:07:49712
713 private:
Matt Menkef6edce752019-03-19 17:21:56714 ClientSocketPool::GroupId last_group_id_;
Tarun Bansal162eabe52018-01-20 01:16:39715 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31716};
717
[email protected]231d5a32008-09-13 00:45:27718//-----------------------------------------------------------------------------
719
[email protected]79cb5c12011-09-12 13:12:04720// Helper functions for validating that AuthChallengeInfo's are correctly
721// configured for common cases.
Emily Starkf2c9bbd2019-04-09 17:08:58722bool CheckBasicServerAuth(
723 const base::Optional<AuthChallengeInfo>& auth_challenge) {
[email protected]79cb5c12011-09-12 13:12:04724 if (!auth_challenge)
725 return false;
726 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43727 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04728 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19729 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04730 return true;
731}
732
Emily Starkf2c9bbd2019-04-09 17:08:58733bool CheckBasicProxyAuth(
734 const base::Optional<AuthChallengeInfo>& auth_challenge) {
[email protected]79cb5c12011-09-12 13:12:04735 if (!auth_challenge)
736 return false;
737 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43738 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
739 EXPECT_EQ("MyRealm1", auth_challenge->realm);
740 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
741 return true;
742}
743
Emily Starkf2c9bbd2019-04-09 17:08:58744bool CheckBasicSecureProxyAuth(
745 const base::Optional<AuthChallengeInfo>& auth_challenge) {
asanka098c0092016-06-16 20:18:43746 if (!auth_challenge)
747 return false;
748 EXPECT_TRUE(auth_challenge->is_proxy);
749 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04750 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19751 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04752 return true;
753}
754
Emily Starkf2c9bbd2019-04-09 17:08:58755bool CheckDigestServerAuth(
756 const base::Optional<AuthChallengeInfo>& auth_challenge) {
[email protected]79cb5c12011-09-12 13:12:04757 if (!auth_challenge)
758 return false;
759 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43760 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04761 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19762 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04763 return true;
764}
765
thakis84dff942015-07-28 20:47:38766#if defined(NTLM_PORTABLE)
Emily Starkf2c9bbd2019-04-09 17:08:58767bool CheckNTLMServerAuth(
768 const base::Optional<AuthChallengeInfo>& auth_challenge) {
[email protected]79cb5c12011-09-12 13:12:04769 if (!auth_challenge)
770 return false;
771 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55772 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04773 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19774 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04775 return true;
776}
David Benjamin5cb91132018-04-06 05:54:49777
Emily Starkf2c9bbd2019-04-09 17:08:58778bool CheckNTLMProxyAuth(
779 const base::Optional<AuthChallengeInfo>& auth_challenge) {
David Benjamin5cb91132018-04-06 05:54:49780 if (!auth_challenge)
781 return false;
782 EXPECT_TRUE(auth_challenge->is_proxy);
783 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
784 EXPECT_EQ(std::string(), auth_challenge->realm);
785 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
786 return true;
787}
thakis84dff942015-07-28 20:47:38788#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04789
[email protected]448d4ca52012-03-04 04:12:23790} // namespace
791
bncd16676a2016-07-20 16:23:01792TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09793 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16794 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27795}
796
bncd16676a2016-07-20 16:23:01797TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27798 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35799 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
800 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06801 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27802 };
Ryan Sleevib8d7ea02018-05-07 20:01:01803 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01804 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27805 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
806 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01807 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22808 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47809 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59810
811 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27812}
813
814// Response with no status line.
bncd16676a2016-07-20 16:23:01815TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27816 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35817 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06818 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27819 };
Ryan Sleevib8d7ea02018-05-07 20:01:01820 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41821 EXPECT_THAT(out.rv, IsOk());
822 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
823 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01824 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41825 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27826}
827
mmenkea7da6da2016-09-01 21:56:52828// Response with no status line, and a weird port. Should fail by default.
829TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
830 MockRead data_reads[] = {
831 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
832 };
833
Ryan Sleevib8d7ea02018-05-07 20:01:01834 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52835 session_deps_.socket_factory->AddSocketDataProvider(&data);
836
837 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
838
krasinc06a72a2016-12-21 03:42:46839 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58840 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19841 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52842
mmenkea7da6da2016-09-01 21:56:52843 request.method = "GET";
844 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10845 request.traffic_annotation =
846 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
847
mmenkea7da6da2016-09-01 21:56:52848 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20849 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52850 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
851}
852
Shivani Sharmafdcaefd2017-11-02 00:12:26853// Tests that request info can be destroyed after the headers phase is complete.
854TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
855 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
856 auto trans =
857 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
858
859 MockRead data_reads[] = {
860 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
861 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
862 };
Ryan Sleevib8d7ea02018-05-07 20:01:01863 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Shivani Sharmafdcaefd2017-11-02 00:12:26864 session_deps_.socket_factory->AddSocketDataProvider(&data);
865
866 TestCompletionCallback callback;
867
868 {
869 auto request = std::make_unique<HttpRequestInfo>();
870 request->method = "GET";
871 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10872 request->traffic_annotation =
873 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26874
875 int rv =
876 trans->Start(request.get(), callback.callback(), NetLogWithSource());
877
878 EXPECT_THAT(callback.GetResult(rv), IsOk());
879 } // Let request info be destroyed.
880
881 trans.reset();
882}
883
mmenkea7da6da2016-09-01 21:56:52884// Response with no status line, and a weird port. Option to allow weird ports
885// enabled.
886TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
887 MockRead data_reads[] = {
888 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
889 };
890
Ryan Sleevib8d7ea02018-05-07 20:01:01891 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52892 session_deps_.socket_factory->AddSocketDataProvider(&data);
893 session_deps_.http_09_on_non_default_ports_enabled = true;
894 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
895
krasinc06a72a2016-12-21 03:42:46896 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58897 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19898 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52899
mmenkea7da6da2016-09-01 21:56:52900 request.method = "GET";
901 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10902 request.traffic_annotation =
903 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
904
mmenkea7da6da2016-09-01 21:56:52905 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20906 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52907 EXPECT_THAT(callback.GetResult(rv), IsOk());
908
909 const HttpResponseInfo* info = trans->GetResponseInfo();
910 ASSERT_TRUE(info->headers);
911 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
912
913 // Don't bother to read the body - that's verified elsewhere, important thing
914 // is that the option to allow HTTP/0.9 on non-default ports is respected.
915}
916
[email protected]231d5a32008-09-13 00:45:27917// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01918TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27919 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35920 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06921 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27922 };
Ryan Sleevib8d7ea02018-05-07 20:01:01923 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01924 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27925 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
926 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01927 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22928 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27929}
930
931// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01932TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27933 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35934 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06935 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27936 };
Ryan Sleevib8d7ea02018-05-07 20:01:01937 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01938 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27939 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
940 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01941 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22942 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27943}
944
945// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01946TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27947 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35948 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06949 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27950 };
Ryan Sleevib8d7ea02018-05-07 20:01:01951 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41952 EXPECT_THAT(out.rv, IsOk());
953 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
954 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01955 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41956 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27957}
958
959// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01960TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27961 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35962 MockRead("\n"),
963 MockRead("\n"),
964 MockRead("Q"),
965 MockRead("J"),
966 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06967 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27968 };
Ryan Sleevib8d7ea02018-05-07 20:01:01969 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01970 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27971 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
972 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01973 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22974 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27975}
976
977// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01978TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27979 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35980 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06981 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27982 };
Ryan Sleevib8d7ea02018-05-07 20:01:01983 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41984 EXPECT_THAT(out.rv, IsOk());
985 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
986 EXPECT_EQ("HTT", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01987 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41988 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52989}
990
[email protected]f9d44aa2008-09-23 23:57:17991// Simulate a 204 response, lacking a Content-Length header, sent over a
992// persistent connection. The response should still terminate since a 204
993// cannot have a response body.
bncd16676a2016-07-20 16:23:01994TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19995 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17996 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35997 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19998 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06999 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:171000 };
Ryan Sleevib8d7ea02018-05-07 20:01:011001 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011002 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:171003 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1004 EXPECT_EQ("", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011005 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221006 int64_t response_size = reads_size - strlen(junk);
1007 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171008}
1009
[email protected]0877e3d2009-10-17 22:29:571010// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011011TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191012 std::string final_chunk = "0\r\n\r\n";
1013 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1014 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571015 MockRead data_reads[] = {
1016 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1017 MockRead("5\r\nHello\r\n"),
1018 MockRead("1\r\n"),
1019 MockRead(" \r\n"),
1020 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191021 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061022 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571023 };
Ryan Sleevib8d7ea02018-05-07 20:01:011024 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011025 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571026 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1027 EXPECT_EQ("Hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011028 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221029 int64_t response_size = reads_size - extra_data.size();
1030 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571031}
1032
[email protected]9fe44f52010-09-23 18:36:001033// Next tests deal with http://crbug.com/56344.
1034
bncd16676a2016-07-20 16:23:011035TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001036 MultipleContentLengthHeadersNoTransferEncoding) {
1037 MockRead data_reads[] = {
1038 MockRead("HTTP/1.1 200 OK\r\n"),
1039 MockRead("Content-Length: 10\r\n"),
1040 MockRead("Content-Length: 5\r\n\r\n"),
1041 };
Ryan Sleevib8d7ea02018-05-07 20:01:011042 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011043 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001044}
1045
bncd16676a2016-07-20 16:23:011046TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041047 DuplicateContentLengthHeadersNoTransferEncoding) {
1048 MockRead data_reads[] = {
1049 MockRead("HTTP/1.1 200 OK\r\n"),
1050 MockRead("Content-Length: 5\r\n"),
1051 MockRead("Content-Length: 5\r\n\r\n"),
1052 MockRead("Hello"),
1053 };
Ryan Sleevib8d7ea02018-05-07 20:01:011054 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011055 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041056 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1057 EXPECT_EQ("Hello", out.response_data);
1058}
1059
bncd16676a2016-07-20 16:23:011060TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041061 ComplexContentLengthHeadersNoTransferEncoding) {
1062 // More than 2 dupes.
1063 {
1064 MockRead data_reads[] = {
1065 MockRead("HTTP/1.1 200 OK\r\n"),
1066 MockRead("Content-Length: 5\r\n"),
1067 MockRead("Content-Length: 5\r\n"),
1068 MockRead("Content-Length: 5\r\n\r\n"),
1069 MockRead("Hello"),
1070 };
Ryan Sleevib8d7ea02018-05-07 20:01:011071 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011072 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041073 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1074 EXPECT_EQ("Hello", out.response_data);
1075 }
1076 // HTTP/1.0
1077 {
1078 MockRead data_reads[] = {
1079 MockRead("HTTP/1.0 200 OK\r\n"),
1080 MockRead("Content-Length: 5\r\n"),
1081 MockRead("Content-Length: 5\r\n"),
1082 MockRead("Content-Length: 5\r\n\r\n"),
1083 MockRead("Hello"),
1084 };
Ryan Sleevib8d7ea02018-05-07 20:01:011085 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011086 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041087 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1088 EXPECT_EQ("Hello", out.response_data);
1089 }
1090 // 2 dupes and one mismatched.
1091 {
1092 MockRead data_reads[] = {
1093 MockRead("HTTP/1.1 200 OK\r\n"),
1094 MockRead("Content-Length: 10\r\n"),
1095 MockRead("Content-Length: 10\r\n"),
1096 MockRead("Content-Length: 5\r\n\r\n"),
1097 };
Ryan Sleevib8d7ea02018-05-07 20:01:011098 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011099 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041100 }
1101}
1102
bncd16676a2016-07-20 16:23:011103TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001104 MultipleContentLengthHeadersTransferEncoding) {
1105 MockRead data_reads[] = {
1106 MockRead("HTTP/1.1 200 OK\r\n"),
1107 MockRead("Content-Length: 666\r\n"),
1108 MockRead("Content-Length: 1337\r\n"),
1109 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1110 MockRead("5\r\nHello\r\n"),
1111 MockRead("1\r\n"),
1112 MockRead(" \r\n"),
1113 MockRead("5\r\nworld\r\n"),
1114 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061115 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001116 };
Ryan Sleevib8d7ea02018-05-07 20:01:011117 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011118 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001119 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1120 EXPECT_EQ("Hello world", out.response_data);
1121}
1122
[email protected]1628fe92011-10-04 23:04:551123// Next tests deal with http://crbug.com/98895.
1124
1125// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011126TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551127 MockRead data_reads[] = {
1128 MockRead("HTTP/1.1 200 OK\r\n"),
1129 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1130 MockRead("Content-Length: 5\r\n\r\n"),
1131 MockRead("Hello"),
1132 };
Ryan Sleevib8d7ea02018-05-07 20:01:011133 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011134 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551135 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1136 EXPECT_EQ("Hello", out.response_data);
1137}
1138
[email protected]54a9c6e52012-03-21 20:10:591139// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011140TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551141 MockRead data_reads[] = {
1142 MockRead("HTTP/1.1 200 OK\r\n"),
1143 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1144 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1145 MockRead("Content-Length: 5\r\n\r\n"),
1146 MockRead("Hello"),
1147 };
Ryan Sleevib8d7ea02018-05-07 20:01:011148 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011149 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591150 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1151 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551152}
1153
1154// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011155TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551156 MockRead data_reads[] = {
1157 MockRead("HTTP/1.1 200 OK\r\n"),
1158 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1159 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1160 MockRead("Content-Length: 5\r\n\r\n"),
1161 MockRead("Hello"),
1162 };
Ryan Sleevib8d7ea02018-05-07 20:01:011163 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011164 EXPECT_THAT(out.rv,
1165 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551166}
1167
[email protected]54a9c6e52012-03-21 20:10:591168// Checks that two identical Location headers result in no error.
1169// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011170TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551171 MockRead data_reads[] = {
1172 MockRead("HTTP/1.1 302 Redirect\r\n"),
1173 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591174 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551175 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061176 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551177 };
1178
1179 HttpRequestInfo request;
1180 request.method = "GET";
1181 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101182 request.traffic_annotation =
1183 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551184
danakj1fd259a02016-04-16 03:17:091185 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161186 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551187
Ryan Sleevib8d7ea02018-05-07 20:01:011188 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071189 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551190
[email protected]49639fa2011-12-20 23:22:411191 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551192
tfarina42834112016-09-22 13:38:201193 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011194 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551195
robpercival214763f2016-07-01 23:27:011196 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551197
bnc691fda62016-08-12 00:43:161198 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521199 ASSERT_TRUE(response);
1200 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551201 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1202 std::string url;
1203 EXPECT_TRUE(response->headers->IsRedirect(&url));
1204 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471205 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551206}
1207
[email protected]1628fe92011-10-04 23:04:551208// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011209TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551210 MockRead data_reads[] = {
1211 MockRead("HTTP/1.1 302 Redirect\r\n"),
1212 MockRead("Location: http://good.com/\r\n"),
1213 MockRead("Location: http://evil.com/\r\n"),
1214 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061215 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551216 };
Ryan Sleevib8d7ea02018-05-07 20:01:011217 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011218 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551219}
1220
[email protected]ef0faf2e72009-03-05 23:27:231221// Do a request using the HEAD method. Verify that we don't try to read the
1222// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011223TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421224 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231225 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231226 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101227 request.traffic_annotation =
1228 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231229
danakj1fd259a02016-04-16 03:17:091230 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161231 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091232 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161233 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091234 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1235 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271236
[email protected]ef0faf2e72009-03-05 23:27:231237 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131238 MockWrite("HEAD / HTTP/1.1\r\n"
1239 "Host: www.example.org\r\n"
1240 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231241 };
1242 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231243 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1244 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231245
mmenked39192ee2015-12-09 00:57:231246 // No response body because the test stops reading here.
1247 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231248 };
1249
Ryan Sleevib8d7ea02018-05-07 20:01:011250 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:071251 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231252
[email protected]49639fa2011-12-20 23:22:411253 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231254
tfarina42834112016-09-22 13:38:201255 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011256 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231257
1258 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011259 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231260
bnc691fda62016-08-12 00:43:161261 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521262 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231263
1264 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521265 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231266 EXPECT_EQ(1234, response->headers->GetContentLength());
1267 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471268 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091269 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1270 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231271
1272 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101273 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231274 bool has_server_header = response->headers->EnumerateHeader(
1275 &iter, "Server", &server_header);
1276 EXPECT_TRUE(has_server_header);
1277 EXPECT_EQ("Blah", server_header);
1278
1279 // Reading should give EOF right away, since there is no message body
1280 // (despite non-zero content-length).
1281 std::string response_data;
bnc691fda62016-08-12 00:43:161282 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011283 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231284 EXPECT_EQ("", response_data);
1285}
1286
bncd16676a2016-07-20 16:23:011287TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091288 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521289
1290 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351291 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1292 MockRead("hello"),
1293 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1294 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061295 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521296 };
Ryan Sleevib8d7ea02018-05-07 20:01:011297 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071298 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521299
[email protected]0b0bf032010-09-21 18:08:501300 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521301 "hello", "world"
1302 };
1303
1304 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421305 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521306 request.method = "GET";
bncce36dca22015-04-21 22:11:231307 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101308 request.traffic_annotation =
1309 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521310
bnc691fda62016-08-12 00:43:161311 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271312
[email protected]49639fa2011-12-20 23:22:411313 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521314
tfarina42834112016-09-22 13:38:201315 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011316 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521317
1318 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011319 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521320
bnc691fda62016-08-12 00:43:161321 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521322 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521323
wezca1070932016-05-26 20:30:521324 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251325 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471326 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521327
1328 std::string response_data;
bnc691fda62016-08-12 00:43:161329 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011330 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251331 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521332 }
1333}
1334
bncd16676a2016-07-20 16:23:011335TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091336 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221337 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191338 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221339 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271340
[email protected]1c773ea12009-04-28 19:58:421341 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521342 request.method = "POST";
1343 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271344 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:101345 request.traffic_annotation =
1346 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521347
shivanishab9a143952016-09-19 17:23:411348 // Check the upload progress returned before initialization is correct.
1349 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1350 EXPECT_EQ(0u, progress.size());
1351 EXPECT_EQ(0u, progress.position());
1352
danakj1fd259a02016-04-16 03:17:091353 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161354 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271355
initial.commit586acc5fe2008-07-26 22:42:521356 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351357 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1358 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1359 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061360 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521361 };
Ryan Sleevib8d7ea02018-05-07 20:01:011362 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071363 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521364
[email protected]49639fa2011-12-20 23:22:411365 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521366
tfarina42834112016-09-22 13:38:201367 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011368 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521369
1370 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011371 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521372
bnc691fda62016-08-12 00:43:161373 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521374 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521375
wezca1070932016-05-26 20:30:521376 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251377 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521378
1379 std::string response_data;
bnc691fda62016-08-12 00:43:161380 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011381 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251382 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521383}
1384
[email protected]3a2d3662009-03-27 03:49:141385// This test is almost the same as Ignores100 above, but the response contains
1386// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571387// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011388TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421389 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141390 request.method = "GET";
1391 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101392 request.traffic_annotation =
1393 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141394
danakj1fd259a02016-04-16 03:17:091395 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161396 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271397
[email protected]3a2d3662009-03-27 03:49:141398 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571399 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1400 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141401 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061402 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141403 };
Ryan Sleevib8d7ea02018-05-07 20:01:011404 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071405 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141406
[email protected]49639fa2011-12-20 23:22:411407 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141408
tfarina42834112016-09-22 13:38:201409 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011410 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141411
1412 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011413 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141414
bnc691fda62016-08-12 00:43:161415 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521416 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141417
wezca1070932016-05-26 20:30:521418 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141419 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1420
1421 std::string response_data;
bnc691fda62016-08-12 00:43:161422 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011423 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141424 EXPECT_EQ("hello world", response_data);
1425}
1426
Andrew Comminos517a92c2019-01-14 17:49:561427TEST_F(HttpNetworkTransactionTest, LoadTimingMeasuresTimeToFirstByteForHttp) {
1428 static const base::TimeDelta kDelayAfterFirstByte =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381429 base::TimeDelta::FromMilliseconds(10);
1430
1431 HttpRequestInfo request;
1432 request.method = "GET";
1433 request.url = GURL("http://www.foo.com/");
1434 request.traffic_annotation =
1435 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1436
1437 std::vector<MockWrite> data_writes = {
1438 MockWrite(ASYNC, 0,
1439 "GET / HTTP/1.1\r\n"
1440 "Host: www.foo.com\r\n"
1441 "Connection: keep-alive\r\n\r\n"),
1442 };
1443
1444 std::vector<MockRead> data_reads = {
1445 // Write one byte of the status line, followed by a pause.
1446 MockRead(ASYNC, 1, "H"),
1447 MockRead(ASYNC, ERR_IO_PENDING, 2),
1448 MockRead(ASYNC, 3, "TTP/1.1 200 OK\r\n\r\n"),
1449 MockRead(ASYNC, 4, "hello world"),
1450 MockRead(SYNCHRONOUS, OK, 5),
1451 };
1452
1453 SequencedSocketData data(data_reads, data_writes);
1454 session_deps_.socket_factory->AddSocketDataProvider(&data);
1455
1456 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1457
1458 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1459
1460 TestCompletionCallback callback;
1461
1462 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1463 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1464
1465 data.RunUntilPaused();
1466 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561467 FastForwardBy(kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381468 data.Resume();
1469
1470 rv = callback.WaitForResult();
1471 EXPECT_THAT(rv, IsOk());
1472
1473 const HttpResponseInfo* response = trans.GetResponseInfo();
1474 ASSERT_TRUE(response);
1475
1476 EXPECT_TRUE(response->headers);
1477 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1478
1479 LoadTimingInfo load_timing_info;
1480 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1481 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1482 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561483 // Ensure we didn't include the delay in the TTFB time.
1484 EXPECT_EQ(load_timing_info.receive_headers_start,
1485 load_timing_info.connect_timing.connect_end);
1486 // Ensure that the mock clock advanced at all.
1487 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1488 kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381489
1490 std::string response_data;
1491 rv = ReadTransaction(&trans, &response_data);
1492 EXPECT_THAT(rv, IsOk());
1493 EXPECT_EQ("hello world", response_data);
1494}
1495
1496// Tests that the time-to-first-byte reported in a transaction's load timing
1497// info uses the first response, even if 1XX/informational.
1498void HttpNetworkTransactionTest::Check100ResponseTiming(bool use_spdy) {
Andrew Comminos517a92c2019-01-14 17:49:561499 static const base::TimeDelta kDelayAfter100Response =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381500 base::TimeDelta::FromMilliseconds(10);
1501
1502 HttpRequestInfo request;
1503 request.method = "GET";
1504 request.url = GURL("https://www.foo.com/");
1505 request.traffic_annotation =
1506 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1507
1508 SSLSocketDataProvider ssl(ASYNC, OK);
1509 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1510
1511 std::vector<MockWrite> data_writes;
1512 std::vector<MockRead> data_reads;
1513
1514 spdy::SpdySerializedFrame spdy_req(
1515 spdy_util_.ConstructSpdyGet(request.url.spec().c_str(), 1, LOWEST));
1516
1517 spdy::SpdyHeaderBlock spdy_resp1_headers;
1518 spdy_resp1_headers[spdy::kHttp2StatusHeader] = "100";
1519 spdy::SpdySerializedFrame spdy_resp1(
1520 spdy_util_.ConstructSpdyReply(1, spdy_resp1_headers.Clone()));
1521 spdy::SpdySerializedFrame spdy_resp2(
1522 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1523 spdy::SpdySerializedFrame spdy_data(
1524 spdy_util_.ConstructSpdyDataFrame(1, "hello world", true));
1525
1526 if (use_spdy) {
1527 ssl.next_proto = kProtoHTTP2;
1528
1529 data_writes = {CreateMockWrite(spdy_req, 0)};
1530
1531 data_reads = {
1532 CreateMockRead(spdy_resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
1533 CreateMockRead(spdy_resp2, 3), CreateMockRead(spdy_data, 4),
1534 MockRead(SYNCHRONOUS, OK, 5),
1535 };
1536 } else {
1537 data_writes = {
1538 MockWrite(ASYNC, 0,
1539 "GET / HTTP/1.1\r\n"
1540 "Host: www.foo.com\r\n"
1541 "Connection: keep-alive\r\n\r\n"),
1542 };
1543
1544 data_reads = {
1545 MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
1546 MockRead(ASYNC, ERR_IO_PENDING, 2),
1547
1548 MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1549 MockRead(ASYNC, 4, "hello world"),
1550 MockRead(SYNCHRONOUS, OK, 5),
1551 };
1552 }
1553
1554 SequencedSocketData data(data_reads, data_writes);
1555 session_deps_.socket_factory->AddSocketDataProvider(&data);
1556
1557 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1558
1559 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1560
1561 TestCompletionCallback callback;
1562
1563 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1564 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1565
1566 data.RunUntilPaused();
1567 // We should now have parsed the 100 response and hit ERR_IO_PENDING. Insert
1568 // the delay before parsing the 200 response.
1569 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561570 FastForwardBy(kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381571 data.Resume();
1572
1573 rv = callback.WaitForResult();
1574 EXPECT_THAT(rv, IsOk());
1575
1576 const HttpResponseInfo* response = trans.GetResponseInfo();
1577 ASSERT_TRUE(response);
1578
1579 LoadTimingInfo load_timing_info;
1580 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1581 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1582 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561583 // Ensure we didn't include the delay in the TTFB time.
1584 EXPECT_EQ(load_timing_info.receive_headers_start,
1585 load_timing_info.connect_timing.connect_end);
1586 // Ensure that the mock clock advanced at all.
1587 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1588 kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381589
1590 std::string response_data;
1591 rv = ReadTransaction(&trans, &response_data);
1592 EXPECT_THAT(rv, IsOk());
1593 EXPECT_EQ("hello world", response_data);
1594}
1595
Andrew Comminos517a92c2019-01-14 17:49:561596TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForHttp) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381597 Check100ResponseTiming(false /* use_spdy */);
1598}
1599
Andrew Comminos517a92c2019-01-14 17:49:561600TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForSpdy) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381601 Check100ResponseTiming(true /* use_spdy */);
1602}
1603
bncd16676a2016-07-20 16:23:011604TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081605 HttpRequestInfo request;
1606 request.method = "POST";
1607 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101608 request.traffic_annotation =
1609 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081610
danakj1fd259a02016-04-16 03:17:091611 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161612 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081613
1614 MockRead data_reads[] = {
1615 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1616 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381617 };
Ryan Sleevib8d7ea02018-05-07 20:01:011618 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
zmo9528c9f42015-08-04 22:12:081619 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381620
zmo9528c9f42015-08-04 22:12:081621 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381622
tfarina42834112016-09-22 13:38:201623 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381625
zmo9528c9f42015-08-04 22:12:081626 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011627 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381628
zmo9528c9f42015-08-04 22:12:081629 std::string response_data;
bnc691fda62016-08-12 00:43:161630 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011631 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081632 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381633}
1634
bncd16676a2016-07-20 16:23:011635TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381636 HttpRequestInfo request;
1637 request.method = "POST";
1638 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101639 request.traffic_annotation =
1640 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381641
danakj1fd259a02016-04-16 03:17:091642 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161643 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271644
[email protected]ee9410e72010-01-07 01:42:381645 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061646 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381647 };
Ryan Sleevib8d7ea02018-05-07 20:01:011648 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071649 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381650
[email protected]49639fa2011-12-20 23:22:411651 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381652
tfarina42834112016-09-22 13:38:201653 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011654 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381655
1656 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011657 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381658}
1659
[email protected]23e482282013-06-14 16:08:021660void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511661 const MockWrite* write_failure,
1662 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421663 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521664 request.method = "GET";
1665 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101666 request.traffic_annotation =
1667 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521668
vishal.b62985ca92015-04-17 08:45:511669 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071670 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091671 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271672
[email protected]202965992011-12-07 23:04:511673 // Written data for successfully sending both requests.
1674 MockWrite data1_writes[] = {
1675 MockWrite("GET / HTTP/1.1\r\n"
1676 "Host: www.foo.com\r\n"
1677 "Connection: keep-alive\r\n\r\n"),
1678 MockWrite("GET / HTTP/1.1\r\n"
1679 "Host: www.foo.com\r\n"
1680 "Connection: keep-alive\r\n\r\n")
1681 };
1682
1683 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521684 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351685 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1686 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061687 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521688 };
[email protected]202965992011-12-07 23:04:511689
1690 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491691 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511692 data1_writes[1] = *write_failure;
1693 } else {
1694 ASSERT_TRUE(read_failure);
1695 data1_reads[2] = *read_failure;
1696 }
1697
Ryan Sleevib8d7ea02018-05-07 20:01:011698 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]bb88e1d32013-05-03 23:11:071699 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521700
1701 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351702 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1703 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061704 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521705 };
Ryan Sleevib8d7ea02018-05-07 20:01:011706 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071707 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521708
thestig9d3bb0c2015-01-24 00:49:511709 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521710 "hello", "world"
1711 };
1712
mikecironef22f9812016-10-04 03:40:191713 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521714 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411715 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521716
bnc691fda62016-08-12 00:43:161717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521718
tfarina42834112016-09-22 13:38:201719 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011720 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521721
1722 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011723 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521724
[email protected]58e32bb2013-01-21 18:23:251725 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161726 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251727 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1728 if (i == 0) {
1729 first_socket_log_id = load_timing_info.socket_log_id;
1730 } else {
1731 // The second request should be using a new socket.
1732 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1733 }
1734
bnc691fda62016-08-12 00:43:161735 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521736 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521737
wezca1070932016-05-26 20:30:521738 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471739 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251740 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521741
1742 std::string response_data;
bnc691fda62016-08-12 00:43:161743 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011744 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251745 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521746 }
1747}
[email protected]3d2a59b2008-09-26 19:44:251748
[email protected]a34f61ee2014-03-18 20:59:491749void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1750 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101751 const MockRead* read_failure,
1752 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491753 HttpRequestInfo request;
1754 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101755 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101756 request.traffic_annotation =
1757 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491758
vishal.b62985ca92015-04-17 08:45:511759 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491760 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091761 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491762
[email protected]09356c652014-03-25 15:36:101763 SSLSocketDataProvider ssl1(ASYNC, OK);
1764 SSLSocketDataProvider ssl2(ASYNC, OK);
1765 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361766 ssl1.next_proto = kProtoHTTP2;
1767 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101768 }
1769 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1770 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491771
[email protected]09356c652014-03-25 15:36:101772 // SPDY versions of the request and response.
Ryan Hamilton0239aac2018-05-19 00:03:131773 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491774 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131775 spdy::SpdySerializedFrame spdy_response(
Raul Tambre94493c652019-03-11 17:18:351776 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131777 spdy::SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191778 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491779
[email protected]09356c652014-03-25 15:36:101780 // HTTP/1.1 versions of the request and response.
1781 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1782 "Host: www.foo.com\r\n"
1783 "Connection: keep-alive\r\n\r\n";
1784 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1785 const char kHttpData[] = "hello";
1786
1787 std::vector<MockRead> data1_reads;
1788 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491789 if (write_failure) {
1790 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101791 data1_writes.push_back(*write_failure);
1792 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491793 } else {
1794 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101795 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411796 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101797 } else {
1798 data1_writes.push_back(MockWrite(kHttpRequest));
1799 }
1800 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491801 }
1802
Ryan Sleevib8d7ea02018-05-07 20:01:011803 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]a34f61ee2014-03-18 20:59:491804 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1805
[email protected]09356c652014-03-25 15:36:101806 std::vector<MockRead> data2_reads;
1807 std::vector<MockWrite> data2_writes;
1808
1809 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411810 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101811
bncdf80d44fd2016-07-15 20:27:411812 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1813 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101814 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1815 } else {
1816 data2_writes.push_back(
1817 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1818
1819 data2_reads.push_back(
1820 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1821 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1822 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1823 }
Ryan Sleevib8d7ea02018-05-07 20:01:011824 SequencedSocketData data2(data2_reads, data2_writes);
[email protected]a34f61ee2014-03-18 20:59:491825 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1826
1827 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591828 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491829 // Wait for the preconnect to complete.
1830 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1831 base::RunLoop().RunUntilIdle();
Matt Menke9d5e2c92019-02-05 01:42:231832 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491833
1834 // Make the request.
1835 TestCompletionCallback callback;
1836
bnc691fda62016-08-12 00:43:161837 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491838
tfarina42834112016-09-22 13:38:201839 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011840 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491841
1842 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011843 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491844
1845 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161846 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101847 TestLoadTimingNotReused(
1848 load_timing_info,
1849 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491850
bnc691fda62016-08-12 00:43:161851 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521852 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491853
wezca1070932016-05-26 20:30:521854 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021855 if (response->was_fetched_via_spdy) {
1856 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1857 } else {
1858 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1859 }
[email protected]a34f61ee2014-03-18 20:59:491860
1861 std::string response_data;
bnc691fda62016-08-12 00:43:161862 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011863 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101864 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491865}
1866
Biljith Jayan45a41722017-08-16 18:43:141867// Test that we do not retry indefinitely when a server sends an error like
1868// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1869// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1870TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1871 HttpRequestInfo request;
1872 request.method = "GET";
1873 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101874 request.traffic_annotation =
1875 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141876
1877 // Check whether we give up after the third try.
1878
1879 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131880 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141881 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131882 spdy::SpdySerializedFrame spdy_response_go_away(
1883 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011884 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1885 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141886
1887 // Three go away responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011888 StaticSocketDataProvider data1(data_read1, data_write);
1889 StaticSocketDataProvider data2(data_read1, data_write);
1890 StaticSocketDataProvider data3(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141891
1892 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1893 AddSSLSocketData();
1894 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1895 AddSSLSocketData();
1896 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1897 AddSSLSocketData();
1898
1899 TestCompletionCallback callback;
1900 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1901 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1902
1903 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1904 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1905
1906 rv = callback.WaitForResult();
1907 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1908}
1909
1910TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1911 HttpRequestInfo request;
1912 request.method = "GET";
1913 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101914 request.traffic_annotation =
1915 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141916
1917 // Check whether we try atleast thrice before giving up.
1918
1919 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131920 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141921 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131922 spdy::SpdySerializedFrame spdy_response_go_away(
1923 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011924 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1925 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141926
1927 // Construct a non error HTTP2 response.
Ryan Hamilton0239aac2018-05-19 00:03:131928 spdy::SpdySerializedFrame spdy_response_no_error(
Biljith Jayan45a41722017-08-16 18:43:141929 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131930 spdy::SpdySerializedFrame spdy_data(
1931 spdy_util_.ConstructSpdyDataFrame(1, true));
Biljith Jayan45a41722017-08-16 18:43:141932 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1933 CreateMockRead(spdy_data, 2)};
1934
1935 // Two error responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011936 StaticSocketDataProvider data1(data_read1, data_write);
1937 StaticSocketDataProvider data2(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141938 // Followed by a success response.
Ryan Sleevib8d7ea02018-05-07 20:01:011939 SequencedSocketData data3(data_read2, data_write);
Biljith Jayan45a41722017-08-16 18:43:141940
1941 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1942 AddSSLSocketData();
1943 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1944 AddSSLSocketData();
1945 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1946 AddSSLSocketData();
1947
1948 TestCompletionCallback callback;
1949 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1950 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1951
1952 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1953 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1954
1955 rv = callback.WaitForResult();
1956 EXPECT_THAT(rv, IsOk());
1957}
1958
bncd16676a2016-07-20 16:23:011959TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061960 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:351961 KeepAliveConnectionResendRequestTest(&write_failure, nullptr);
[email protected]202965992011-12-07 23:04:511962}
1963
bncd16676a2016-07-20 16:23:011964TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061965 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:351966 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251967}
1968
bncd16676a2016-07-20 16:23:011969TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061970 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351971 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251972}
1973
[email protected]d58ceea82014-06-04 10:55:541974// Make sure that on a 408 response (Request Timeout), the request is retried,
1975// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011976TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541977 MockRead read_failure(SYNCHRONOUS,
1978 "HTTP/1.1 408 Request Timeout\r\n"
1979 "Connection: Keep-Alive\r\n"
1980 "Content-Length: 6\r\n\r\n"
1981 "Pickle");
Raul Tambre94493c652019-03-11 17:18:351982 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]d58ceea82014-06-04 10:55:541983}
1984
bncd16676a2016-07-20 16:23:011985TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491986 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:351987 PreconnectErrorResendRequestTest(&write_failure, nullptr, false);
[email protected]a34f61ee2014-03-18 20:59:491988}
1989
bncd16676a2016-07-20 16:23:011990TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491991 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:351992 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491993}
1994
bncd16676a2016-07-20 16:23:011995TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491996 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351997 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]09356c652014-03-25 15:36:101998}
1999
bncd16676a2016-07-20 16:23:012000TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:102001 MockRead read_failure(ASYNC, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352002 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]09356c652014-03-25 15:36:102003}
2004
[email protected]d58ceea82014-06-04 10:55:542005// Make sure that on a 408 response (Request Timeout), the request is retried,
2006// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:012007TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:542008 MockRead read_failure(SYNCHRONOUS,
2009 "HTTP/1.1 408 Request Timeout\r\n"
2010 "Connection: Keep-Alive\r\n"
2011 "Content-Length: 6\r\n\r\n"
2012 "Pickle");
Raul Tambre94493c652019-03-11 17:18:352013 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
2014 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]d58ceea82014-06-04 10:55:542015}
2016
bncd16676a2016-07-20 16:23:012017TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:102018 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:352019 PreconnectErrorResendRequestTest(&write_failure, nullptr, true);
[email protected]09356c652014-03-25 15:36:102020}
2021
bncd16676a2016-07-20 16:23:012022TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:102023 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:352024 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]09356c652014-03-25 15:36:102025}
2026
bncd16676a2016-07-20 16:23:012027TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:102028 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352029 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]09356c652014-03-25 15:36:102030}
2031
bncd16676a2016-07-20 16:23:012032TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:102033 MockRead read_failure(ASYNC, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352034 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:492035}
2036
bncd16676a2016-07-20 16:23:012037TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:422038 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:252039 request.method = "GET";
bncce36dca22015-04-21 22:11:232040 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102041 request.traffic_annotation =
2042 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:252043
danakj1fd259a02016-04-16 03:17:092044 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162045 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272046
[email protected]3d2a59b2008-09-26 19:44:252047 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062048 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:352049 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2050 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062051 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252052 };
Ryan Sleevib8d7ea02018-05-07 20:01:012053 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072054 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:252055
[email protected]49639fa2011-12-20 23:22:412056 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:252057
tfarina42834112016-09-22 13:38:202058 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012059 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:252060
2061 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012062 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:592063
2064 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162065 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592066 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:252067}
2068
2069// What do various browsers do when the server closes a non-keepalive
2070// connection without sending any response header or body?
2071//
2072// IE7: error page
2073// Safari 3.1.2 (Windows): error page
2074// Firefox 3.0.1: blank page
2075// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:422076// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
2077// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:012078TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:252079 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062080 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:352081 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2082 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062083 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252084 };
Ryan Sleevib8d7ea02018-05-07 20:01:012085 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:012086 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:252087}
[email protected]1826a402014-01-08 15:40:482088
[email protected]7a5378b2012-11-04 03:25:172089// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
2090// tests. There was a bug causing HttpNetworkTransaction to hang in the
2091// destructor in such situations.
2092// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:012093TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:172094 HttpRequestInfo request;
2095 request.method = "GET";
bncce36dca22015-04-21 22:11:232096 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102097 request.traffic_annotation =
2098 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172099
danakj1fd259a02016-04-16 03:17:092100 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582101 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192102 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172103
2104 MockRead data_reads[] = {
2105 MockRead("HTTP/1.0 200 OK\r\n"),
2106 MockRead("Connection: keep-alive\r\n"),
2107 MockRead("Content-Length: 100\r\n\r\n"),
2108 MockRead("hello"),
2109 MockRead(SYNCHRONOUS, 0),
2110 };
Ryan Sleevib8d7ea02018-05-07 20:01:012111 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072112 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172113
2114 TestCompletionCallback callback;
2115
tfarina42834112016-09-22 13:38:202116 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012117 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172118
2119 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012120 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172121
Victor Costan9c7302b2018-08-27 16:39:442122 scoped_refptr<IOBufferWithSize> io_buf =
2123 base::MakeRefCounted<IOBufferWithSize>(100);
[email protected]90499482013-06-01 00:39:502124 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172125 if (rv == ERR_IO_PENDING)
2126 rv = callback.WaitForResult();
2127 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:502128 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:012129 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172130
2131 trans.reset();
fdoray92e35a72016-06-10 15:54:552132 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172133 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2134}
2135
bncd16676a2016-07-20 16:23:012136TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:172137 HttpRequestInfo request;
2138 request.method = "GET";
bncce36dca22015-04-21 22:11:232139 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102140 request.traffic_annotation =
2141 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172142
danakj1fd259a02016-04-16 03:17:092143 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582144 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192145 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172146
2147 MockRead data_reads[] = {
2148 MockRead("HTTP/1.0 200 OK\r\n"),
2149 MockRead("Connection: keep-alive\r\n"),
2150 MockRead("Content-Length: 100\r\n\r\n"),
2151 MockRead(SYNCHRONOUS, 0),
2152 };
Ryan Sleevib8d7ea02018-05-07 20:01:012153 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072154 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172155
2156 TestCompletionCallback callback;
2157
tfarina42834112016-09-22 13:38:202158 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012159 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172160
2161 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012162 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172163
Victor Costan9c7302b2018-08-27 16:39:442164 scoped_refptr<IOBufferWithSize> io_buf(
2165 base::MakeRefCounted<IOBufferWithSize>(100));
[email protected]90499482013-06-01 00:39:502166 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172167 if (rv == ERR_IO_PENDING)
2168 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012169 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172170
2171 trans.reset();
fdoray92e35a72016-06-10 15:54:552172 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172173 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2174}
2175
[email protected]0b0bf032010-09-21 18:08:502176// Test that we correctly reuse a keep-alive connection after not explicitly
2177// reading the body.
bncd16676a2016-07-20 16:23:012178TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132179 HttpRequestInfo request;
2180 request.method = "GET";
2181 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102182 request.traffic_annotation =
2183 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132184
vishal.b62985ca92015-04-17 08:45:512185 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072186 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092187 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272188
mmenkecc2298e2015-12-07 18:20:182189 const char* request_data =
2190 "GET / HTTP/1.1\r\n"
2191 "Host: www.foo.com\r\n"
2192 "Connection: keep-alive\r\n\r\n";
2193 MockWrite data_writes[] = {
2194 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2195 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2196 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2197 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2198 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2199 };
2200
[email protected]0b0bf032010-09-21 18:08:502201 // Note that because all these reads happen in the same
2202 // StaticSocketDataProvider, it shows that the same socket is being reused for
2203 // all transactions.
mmenkecc2298e2015-12-07 18:20:182204 MockRead data_reads[] = {
2205 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2206 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2207 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2208 MockRead(ASYNC, 7,
2209 "HTTP/1.1 302 Found\r\n"
2210 "Content-Length: 0\r\n\r\n"),
2211 MockRead(ASYNC, 9,
2212 "HTTP/1.1 302 Found\r\n"
2213 "Content-Length: 5\r\n\r\n"
2214 "hello"),
2215 MockRead(ASYNC, 11,
2216 "HTTP/1.1 301 Moved Permanently\r\n"
2217 "Content-Length: 0\r\n\r\n"),
2218 MockRead(ASYNC, 13,
2219 "HTTP/1.1 301 Moved Permanently\r\n"
2220 "Content-Length: 5\r\n\r\n"
2221 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132222
mmenkecc2298e2015-12-07 18:20:182223 // In the next two rounds, IsConnectedAndIdle returns false, due to
2224 // the set_busy_before_sync_reads(true) call, while the
2225 // HttpNetworkTransaction is being shut down, but the socket is still
2226 // reuseable. See http://crbug.com/544255.
2227 MockRead(ASYNC, 15,
2228 "HTTP/1.1 200 Hunky-Dory\r\n"
2229 "Content-Length: 5\r\n\r\n"),
2230 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132231
mmenkecc2298e2015-12-07 18:20:182232 MockRead(ASYNC, 18,
2233 "HTTP/1.1 200 Hunky-Dory\r\n"
2234 "Content-Length: 5\r\n\r\n"
2235 "he"),
2236 MockRead(SYNCHRONOUS, 19, "llo"),
2237
2238 // The body of the final request is actually read.
2239 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2240 MockRead(ASYNC, 22, "hello"),
2241 };
Ryan Sleevib8d7ea02018-05-07 20:01:012242 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182243 data.set_busy_before_sync_reads(true);
2244 session_deps_.socket_factory->AddSocketDataProvider(&data);
2245
Avi Drissman4365a4782018-12-28 19:26:242246 const int kNumUnreadBodies = base::size(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502247 std::string response_lines[kNumUnreadBodies];
2248
mikecironef22f9812016-10-04 03:40:192249 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182250 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412251 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132252
Jeremy Roman0579ed62017-08-29 15:56:192253 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582254 session.get());
[email protected]fc31d6a42010-06-24 18:05:132255
tfarina42834112016-09-22 13:38:202256 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012257 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132258
[email protected]58e32bb2013-01-21 18:23:252259 LoadTimingInfo load_timing_info;
2260 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2261 if (i == 0) {
2262 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2263 first_socket_log_id = load_timing_info.socket_log_id;
2264 } else {
2265 TestLoadTimingReused(load_timing_info);
2266 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2267 }
2268
[email protected]fc31d6a42010-06-24 18:05:132269 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182270 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132271
mmenkecc2298e2015-12-07 18:20:182272 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502273 response_lines[i] = response->headers->GetStatusLine();
2274
mmenkecc2298e2015-12-07 18:20:182275 // Delete the transaction without reading the response bodies. Then spin
2276 // the message loop, so the response bodies are drained.
2277 trans.reset();
2278 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132279 }
[email protected]0b0bf032010-09-21 18:08:502280
2281 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182282 "HTTP/1.1 204 No Content",
2283 "HTTP/1.1 205 Reset Content",
2284 "HTTP/1.1 304 Not Modified",
2285 "HTTP/1.1 302 Found",
2286 "HTTP/1.1 302 Found",
2287 "HTTP/1.1 301 Moved Permanently",
2288 "HTTP/1.1 301 Moved Permanently",
2289 "HTTP/1.1 200 Hunky-Dory",
2290 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502291 };
2292
Avi Drissman4365a4782018-12-28 19:26:242293 static_assert(kNumUnreadBodies == base::size(kStatusLines),
mostynb91e0da982015-01-20 19:17:272294 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502295
2296 for (int i = 0; i < kNumUnreadBodies; ++i)
2297 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2298
[email protected]49639fa2011-12-20 23:22:412299 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162300 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202301 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012302 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162303 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182304 ASSERT_TRUE(response);
2305 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502306 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2307 std::string response_data;
bnc691fda62016-08-12 00:43:162308 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012309 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502310 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132311}
2312
mmenke5f94fda2016-06-02 20:54:132313// Sockets that receive extra data after a response is complete should not be
2314// reused.
bncd16676a2016-07-20 16:23:012315TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132316 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2317 MockWrite data_writes1[] = {
2318 MockWrite("HEAD / HTTP/1.1\r\n"
2319 "Host: www.borked.com\r\n"
2320 "Connection: keep-alive\r\n\r\n"),
2321 };
2322
2323 MockRead data_reads1[] = {
2324 MockRead("HTTP/1.1 200 OK\r\n"
2325 "Connection: keep-alive\r\n"
2326 "Content-Length: 22\r\n\r\n"
2327 "This server is borked."),
2328 };
2329
2330 MockWrite data_writes2[] = {
2331 MockWrite("GET /foo HTTP/1.1\r\n"
2332 "Host: www.borked.com\r\n"
2333 "Connection: keep-alive\r\n\r\n"),
2334 };
2335
2336 MockRead data_reads2[] = {
2337 MockRead("HTTP/1.1 200 OK\r\n"
2338 "Content-Length: 3\r\n\r\n"
2339 "foo"),
2340 };
Ryan Sleevib8d7ea02018-05-07 20:01:012341 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132342 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012343 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132344 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2345
2346 TestCompletionCallback callback;
2347 HttpRequestInfo request1;
2348 request1.method = "HEAD";
2349 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102350 request1.traffic_annotation =
2351 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132352
bnc87dcefc2017-05-25 12:47:582353 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192354 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202355 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012356 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132357
2358 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2359 ASSERT_TRUE(response1);
2360 ASSERT_TRUE(response1->headers);
2361 EXPECT_EQ(200, response1->headers->response_code());
2362 EXPECT_TRUE(response1->headers->IsKeepAlive());
2363
2364 std::string response_data1;
robpercival214763f2016-07-01 23:27:012365 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132366 EXPECT_EQ("", response_data1);
2367 // Deleting the transaction attempts to release the socket back into the
2368 // socket pool.
2369 trans1.reset();
2370
2371 HttpRequestInfo request2;
2372 request2.method = "GET";
2373 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102374 request2.traffic_annotation =
2375 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132376
bnc87dcefc2017-05-25 12:47:582377 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192378 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202379 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012380 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132381
2382 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2383 ASSERT_TRUE(response2);
2384 ASSERT_TRUE(response2->headers);
2385 EXPECT_EQ(200, response2->headers->response_code());
2386
2387 std::string response_data2;
robpercival214763f2016-07-01 23:27:012388 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132389 EXPECT_EQ("foo", response_data2);
2390}
2391
bncd16676a2016-07-20 16:23:012392TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2394 MockWrite data_writes1[] = {
2395 MockWrite("GET / HTTP/1.1\r\n"
2396 "Host: www.borked.com\r\n"
2397 "Connection: keep-alive\r\n\r\n"),
2398 };
2399
2400 MockRead data_reads1[] = {
2401 MockRead("HTTP/1.1 200 OK\r\n"
2402 "Connection: keep-alive\r\n"
2403 "Content-Length: 22\r\n\r\n"
2404 "This server is borked."
2405 "Bonus data!"),
2406 };
2407
2408 MockWrite data_writes2[] = {
2409 MockWrite("GET /foo HTTP/1.1\r\n"
2410 "Host: www.borked.com\r\n"
2411 "Connection: keep-alive\r\n\r\n"),
2412 };
2413
2414 MockRead data_reads2[] = {
2415 MockRead("HTTP/1.1 200 OK\r\n"
2416 "Content-Length: 3\r\n\r\n"
2417 "foo"),
2418 };
Ryan Sleevib8d7ea02018-05-07 20:01:012419 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132420 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012421 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132422 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2423
2424 TestCompletionCallback callback;
2425 HttpRequestInfo request1;
2426 request1.method = "GET";
2427 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102428 request1.traffic_annotation =
2429 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132430
bnc87dcefc2017-05-25 12:47:582431 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192432 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202433 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012434 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132435
2436 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2437 ASSERT_TRUE(response1);
2438 ASSERT_TRUE(response1->headers);
2439 EXPECT_EQ(200, response1->headers->response_code());
2440 EXPECT_TRUE(response1->headers->IsKeepAlive());
2441
2442 std::string response_data1;
robpercival214763f2016-07-01 23:27:012443 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132444 EXPECT_EQ("This server is borked.", response_data1);
2445 // Deleting the transaction attempts to release the socket back into the
2446 // socket pool.
2447 trans1.reset();
2448
2449 HttpRequestInfo request2;
2450 request2.method = "GET";
2451 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102452 request2.traffic_annotation =
2453 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132454
bnc87dcefc2017-05-25 12:47:582455 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192456 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202457 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012458 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132459
2460 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2461 ASSERT_TRUE(response2);
2462 ASSERT_TRUE(response2->headers);
2463 EXPECT_EQ(200, response2->headers->response_code());
2464
2465 std::string response_data2;
robpercival214763f2016-07-01 23:27:012466 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132467 EXPECT_EQ("foo", response_data2);
2468}
2469
bncd16676a2016-07-20 16:23:012470TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2472 MockWrite data_writes1[] = {
2473 MockWrite("GET / HTTP/1.1\r\n"
2474 "Host: www.borked.com\r\n"
2475 "Connection: keep-alive\r\n\r\n"),
2476 };
2477
2478 MockRead data_reads1[] = {
2479 MockRead("HTTP/1.1 200 OK\r\n"
2480 "Connection: keep-alive\r\n"
2481 "Transfer-Encoding: chunked\r\n\r\n"),
2482 MockRead("16\r\nThis server is borked.\r\n"),
2483 MockRead("0\r\n\r\nBonus data!"),
2484 };
2485
2486 MockWrite data_writes2[] = {
2487 MockWrite("GET /foo HTTP/1.1\r\n"
2488 "Host: www.borked.com\r\n"
2489 "Connection: keep-alive\r\n\r\n"),
2490 };
2491
2492 MockRead data_reads2[] = {
2493 MockRead("HTTP/1.1 200 OK\r\n"
2494 "Content-Length: 3\r\n\r\n"
2495 "foo"),
2496 };
Ryan Sleevib8d7ea02018-05-07 20:01:012497 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132498 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012499 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132500 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2501
2502 TestCompletionCallback callback;
2503 HttpRequestInfo request1;
2504 request1.method = "GET";
2505 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102506 request1.traffic_annotation =
2507 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132508
bnc87dcefc2017-05-25 12:47:582509 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192510 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202511 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012512 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132513
2514 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2515 ASSERT_TRUE(response1);
2516 ASSERT_TRUE(response1->headers);
2517 EXPECT_EQ(200, response1->headers->response_code());
2518 EXPECT_TRUE(response1->headers->IsKeepAlive());
2519
2520 std::string response_data1;
robpercival214763f2016-07-01 23:27:012521 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132522 EXPECT_EQ("This server is borked.", response_data1);
2523 // Deleting the transaction attempts to release the socket back into the
2524 // socket pool.
2525 trans1.reset();
2526
2527 HttpRequestInfo request2;
2528 request2.method = "GET";
2529 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102530 request2.traffic_annotation =
2531 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132532
bnc87dcefc2017-05-25 12:47:582533 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192534 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202535 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012536 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132537
2538 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2539 ASSERT_TRUE(response2);
2540 ASSERT_TRUE(response2->headers);
2541 EXPECT_EQ(200, response2->headers->response_code());
2542
2543 std::string response_data2;
robpercival214763f2016-07-01 23:27:012544 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132545 EXPECT_EQ("foo", response_data2);
2546}
2547
2548// This is a little different from the others - it tests the case that the
2549// HttpStreamParser doesn't know if there's extra data on a socket or not when
2550// the HttpNetworkTransaction is torn down, because the response body hasn't
2551// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012552TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132553 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2554 MockWrite data_writes1[] = {
2555 MockWrite("GET / HTTP/1.1\r\n"
2556 "Host: www.borked.com\r\n"
2557 "Connection: keep-alive\r\n\r\n"),
2558 };
2559
2560 MockRead data_reads1[] = {
2561 MockRead("HTTP/1.1 200 OK\r\n"
2562 "Connection: keep-alive\r\n"
2563 "Transfer-Encoding: chunked\r\n\r\n"),
2564 MockRead("16\r\nThis server is borked.\r\n"),
2565 MockRead("0\r\n\r\nBonus data!"),
2566 };
Ryan Sleevib8d7ea02018-05-07 20:01:012567 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132568 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2569
2570 TestCompletionCallback callback;
2571 HttpRequestInfo request1;
2572 request1.method = "GET";
2573 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102574 request1.traffic_annotation =
2575 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132576
bnc87dcefc2017-05-25 12:47:582577 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192578 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582579 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012580 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132581
bnc87dcefc2017-05-25 12:47:582582 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132583 ASSERT_TRUE(response1);
2584 ASSERT_TRUE(response1->headers);
2585 EXPECT_EQ(200, response1->headers->response_code());
2586 EXPECT_TRUE(response1->headers->IsKeepAlive());
2587
2588 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2589 // response body.
bnc87dcefc2017-05-25 12:47:582590 trans.reset();
mmenke5f94fda2016-06-02 20:54:132591
2592 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2593 // socket can't be reused, rather than returning it to the socket pool.
2594 base::RunLoop().RunUntilIdle();
2595
2596 // There should be no idle sockets in the pool.
2597 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2598}
2599
[email protected]038e9a32008-10-08 22:40:162600// Test the request-challenge-retry sequence for basic auth.
2601// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012602TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422603 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162604 request.method = "GET";
bncce36dca22015-04-21 22:11:232605 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102606 request.traffic_annotation =
2607 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162608
vishal.b62985ca92015-04-17 08:45:512609 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072610 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092611 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162612 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272613
[email protected]f9ee6b52008-11-08 06:46:232614 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232615 MockWrite(
2616 "GET / HTTP/1.1\r\n"
2617 "Host: www.example.org\r\n"
2618 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232619 };
2620
[email protected]038e9a32008-10-08 22:40:162621 MockRead data_reads1[] = {
2622 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2623 // Give a couple authenticate options (only the middle one is actually
2624 // supported).
[email protected]22927ad2009-09-21 19:56:192625 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162626 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2627 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2628 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2629 // Large content-length -- won't matter, as connection will be reset.
2630 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062631 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162632 };
2633
2634 // After calling trans->RestartWithAuth(), this is the request we should
2635 // be issuing -- the final header line contains the credentials.
2636 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232637 MockWrite(
2638 "GET / HTTP/1.1\r\n"
2639 "Host: www.example.org\r\n"
2640 "Connection: keep-alive\r\n"
2641 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162642 };
2643
2644 // Lastly, the server responds with the actual content.
2645 MockRead data_reads2[] = {
2646 MockRead("HTTP/1.0 200 OK\r\n"),
2647 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2648 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062649 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162650 };
2651
Ryan Sleevib8d7ea02018-05-07 20:01:012652 StaticSocketDataProvider data1(data_reads1, data_writes1);
2653 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072654 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2655 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162656
[email protected]49639fa2011-12-20 23:22:412657 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162658
tfarina42834112016-09-22 13:38:202659 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012660 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162661
2662 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012663 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162664
[email protected]58e32bb2013-01-21 18:23:252665 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162666 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252667 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2668
Ryan Sleevib8d7ea02018-05-07 20:01:012669 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162670 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012671 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162672 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192673
bnc691fda62016-08-12 00:43:162674 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522675 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582676 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]038e9a32008-10-08 22:40:162677
[email protected]49639fa2011-12-20 23:22:412678 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162679
bnc691fda62016-08-12 00:43:162680 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012681 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162682
2683 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012684 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162685
[email protected]58e32bb2013-01-21 18:23:252686 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162687 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252688 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2689 // The load timing after restart should have a new socket ID, and times after
2690 // those of the first load timing.
2691 EXPECT_LE(load_timing_info1.receive_headers_end,
2692 load_timing_info2.connect_timing.connect_start);
2693 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2694
Ryan Sleevib8d7ea02018-05-07 20:01:012695 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162696 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012697 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162698 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192699
bnc691fda62016-08-12 00:43:162700 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522701 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582702 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]038e9a32008-10-08 22:40:162703 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162704}
2705
ttuttled9dbc652015-09-29 20:00:592706// Test the request-challenge-retry sequence for basic auth.
2707// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012708TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592709 HttpRequestInfo request;
2710 request.method = "GET";
2711 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102712 request.traffic_annotation =
2713 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592714
2715 TestNetLog log;
2716 MockHostResolver* resolver = new MockHostResolver();
2717 session_deps_.net_log = &log;
2718 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092719 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162720 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592721
2722 resolver->rules()->ClearRules();
2723 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2724
2725 MockWrite data_writes1[] = {
2726 MockWrite("GET / HTTP/1.1\r\n"
2727 "Host: www.example.org\r\n"
2728 "Connection: keep-alive\r\n\r\n"),
2729 };
2730
2731 MockRead data_reads1[] = {
2732 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2733 // Give a couple authenticate options (only the middle one is actually
2734 // supported).
2735 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2736 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2737 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2738 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2739 // Large content-length -- won't matter, as connection will be reset.
2740 MockRead("Content-Length: 10000\r\n\r\n"),
2741 MockRead(SYNCHRONOUS, ERR_FAILED),
2742 };
2743
2744 // After calling trans->RestartWithAuth(), this is the request we should
2745 // be issuing -- the final header line contains the credentials.
2746 MockWrite data_writes2[] = {
2747 MockWrite("GET / HTTP/1.1\r\n"
2748 "Host: www.example.org\r\n"
2749 "Connection: keep-alive\r\n"
2750 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2751 };
2752
2753 // Lastly, the server responds with the actual content.
2754 MockRead data_reads2[] = {
2755 MockRead("HTTP/1.0 200 OK\r\n"),
2756 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2757 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2758 };
2759
Ryan Sleevib8d7ea02018-05-07 20:01:012760 StaticSocketDataProvider data1(data_reads1, data_writes1);
2761 StaticSocketDataProvider data2(data_reads2, data_writes2);
ttuttled9dbc652015-09-29 20:00:592762 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2763 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2764
2765 TestCompletionCallback callback1;
2766
bnc691fda62016-08-12 00:43:162767 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202768 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592769
2770 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162771 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592772 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2773
Ryan Sleevib8d7ea02018-05-07 20:01:012774 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162775 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012776 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162777 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592778
bnc691fda62016-08-12 00:43:162779 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592780 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582781 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
ttuttled9dbc652015-09-29 20:00:592782
2783 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162784 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592785 ASSERT_FALSE(endpoint.address().empty());
2786 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2787
2788 resolver->rules()->ClearRules();
2789 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2790
2791 TestCompletionCallback callback2;
2792
bnc691fda62016-08-12 00:43:162793 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592794 AuthCredentials(kFoo, kBar), callback2.callback())));
2795
2796 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162797 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592798 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2799 // The load timing after restart should have a new socket ID, and times after
2800 // those of the first load timing.
2801 EXPECT_LE(load_timing_info1.receive_headers_end,
2802 load_timing_info2.connect_timing.connect_start);
2803 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2804
Ryan Sleevib8d7ea02018-05-07 20:01:012805 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162806 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012807 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162808 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592809
bnc691fda62016-08-12 00:43:162810 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592811 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582812 EXPECT_FALSE(response->auth_challenge.has_value());
ttuttled9dbc652015-09-29 20:00:592813 EXPECT_EQ(100, response->headers->GetContentLength());
2814
bnc691fda62016-08-12 00:43:162815 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592816 ASSERT_FALSE(endpoint.address().empty());
2817 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2818}
2819
David Benjamin83ddfb32018-03-30 01:07:522820// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2821// will eventually give up.
2822TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2823 HttpRequestInfo request;
2824 request.method = "GET";
2825 request.url = GURL("http://www.example.org/");
2826 request.traffic_annotation =
2827 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2828
2829 TestNetLog log;
2830 session_deps_.net_log = &log;
2831 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2832 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2833
2834 MockWrite data_writes[] = {
2835 MockWrite("GET / HTTP/1.1\r\n"
2836 "Host: www.example.org\r\n"
2837 "Connection: keep-alive\r\n\r\n"),
2838 };
2839
2840 MockRead data_reads[] = {
2841 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2842 // Give a couple authenticate options (only the middle one is actually
2843 // supported).
2844 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2845 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2846 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2847 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2848 // Large content-length -- won't matter, as connection will be reset.
2849 MockRead("Content-Length: 10000\r\n\r\n"),
2850 MockRead(SYNCHRONOUS, ERR_FAILED),
2851 };
2852
2853 // After calling trans->RestartWithAuth(), this is the request we should
2854 // be issuing -- the final header line contains the credentials.
2855 MockWrite data_writes_restart[] = {
2856 MockWrite("GET / HTTP/1.1\r\n"
2857 "Host: www.example.org\r\n"
2858 "Connection: keep-alive\r\n"
2859 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2860 };
2861
Ryan Sleevib8d7ea02018-05-07 20:01:012862 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin83ddfb32018-03-30 01:07:522863 session_deps_.socket_factory->AddSocketDataProvider(&data);
2864
2865 TestCompletionCallback callback;
2866 int rv = callback.GetResult(
2867 trans.Start(&request, callback.callback(), NetLogWithSource()));
2868
2869 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2870 for (int i = 0; i < 32; i++) {
2871 // Check the previous response was a 401.
2872 EXPECT_THAT(rv, IsOk());
2873 const HttpResponseInfo* response = trans.GetResponseInfo();
2874 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582875 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
David Benjamin83ddfb32018-03-30 01:07:522876
2877 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:012878 data_reads, data_writes_restart));
David Benjamin83ddfb32018-03-30 01:07:522879 session_deps_.socket_factory->AddSocketDataProvider(
2880 data_restarts.back().get());
2881 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2882 callback.callback()));
2883 }
2884
2885 // After too many tries, the transaction should have given up.
2886 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2887}
2888
bncd16676a2016-07-20 16:23:012889TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462890 HttpRequestInfo request;
2891 request.method = "GET";
bncce36dca22015-04-21 22:11:232892 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292893 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:102894 request.traffic_annotation =
2895 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462896
danakj1fd259a02016-04-16 03:17:092897 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162898 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272899
[email protected]861fcd52009-08-26 02:33:462900 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232901 MockWrite(
2902 "GET / HTTP/1.1\r\n"
2903 "Host: www.example.org\r\n"
2904 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462905 };
2906
2907 MockRead data_reads[] = {
2908 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2909 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2910 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2911 // Large content-length -- won't matter, as connection will be reset.
2912 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062913 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462914 };
2915
Ryan Sleevib8d7ea02018-05-07 20:01:012916 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:072917 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412918 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462919
tfarina42834112016-09-22 13:38:202920 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012921 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462922
2923 rv = callback.WaitForResult();
2924 EXPECT_EQ(0, rv);
2925
Ryan Sleevib8d7ea02018-05-07 20:01:012926 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162927 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012928 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162929 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192930
bnc691fda62016-08-12 00:43:162931 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522932 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582933 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]861fcd52009-08-26 02:33:462934}
2935
[email protected]2d2697f92009-02-18 21:00:322936// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2937// connection.
bncd16676a2016-07-20 16:23:012938TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182939 // On the second pass, the body read of the auth challenge is synchronous, so
2940 // IsConnectedAndIdle returns false. The socket should still be drained and
2941 // reused. See http://crbug.com/544255.
2942 for (int i = 0; i < 2; ++i) {
2943 HttpRequestInfo request;
2944 request.method = "GET";
2945 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102946 request.traffic_annotation =
2947 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322948
mmenkecc2298e2015-12-07 18:20:182949 TestNetLog log;
2950 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092951 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272952
mmenkecc2298e2015-12-07 18:20:182953 MockWrite data_writes[] = {
2954 MockWrite(ASYNC, 0,
2955 "GET / HTTP/1.1\r\n"
2956 "Host: www.example.org\r\n"
2957 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322958
bnc691fda62016-08-12 00:43:162959 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182960 // be issuing -- the final header line contains the credentials.
2961 MockWrite(ASYNC, 6,
2962 "GET / HTTP/1.1\r\n"
2963 "Host: www.example.org\r\n"
2964 "Connection: keep-alive\r\n"
2965 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2966 };
[email protected]2d2697f92009-02-18 21:00:322967
mmenkecc2298e2015-12-07 18:20:182968 MockRead data_reads[] = {
2969 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2970 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2971 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2972 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2973 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322974
mmenkecc2298e2015-12-07 18:20:182975 // Lastly, the server responds with the actual content.
2976 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2977 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2978 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2979 MockRead(ASYNC, 10, "Hello"),
2980 };
[email protected]2d2697f92009-02-18 21:00:322981
Ryan Sleevib8d7ea02018-05-07 20:01:012982 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182983 data.set_busy_before_sync_reads(true);
2984 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462985
mmenkecc2298e2015-12-07 18:20:182986 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322987
bnc691fda62016-08-12 00:43:162988 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202989 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012990 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322991
mmenkecc2298e2015-12-07 18:20:182992 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162993 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182994 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322995
bnc691fda62016-08-12 00:43:162996 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182997 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582998 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]2d2697f92009-02-18 21:00:322999
mmenkecc2298e2015-12-07 18:20:183000 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:253001
bnc691fda62016-08-12 00:43:163002 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
3003 callback2.callback());
robpercival214763f2016-07-01 23:27:013004 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323005
mmenkecc2298e2015-12-07 18:20:183006 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:163007 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:183008 TestLoadTimingReused(load_timing_info2);
3009 // The load timing after restart should have the same socket ID, and times
3010 // those of the first load timing.
3011 EXPECT_LE(load_timing_info1.receive_headers_end,
3012 load_timing_info2.send_start);
3013 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:323014
bnc691fda62016-08-12 00:43:163015 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:183016 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583017 EXPECT_FALSE(response->auth_challenge.has_value());
mmenkecc2298e2015-12-07 18:20:183018 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323019
mmenkecc2298e2015-12-07 18:20:183020 std::string response_data;
bnc691fda62016-08-12 00:43:163021 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:323022
Ryan Sleevib8d7ea02018-05-07 20:01:013023 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:163024 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:013025 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:163026 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:183027 }
[email protected]2d2697f92009-02-18 21:00:323028}
3029
3030// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3031// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:013032TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:423033 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323034 request.method = "GET";
bncce36dca22015-04-21 22:11:233035 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103036 request.traffic_annotation =
3037 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323038
danakj1fd259a02016-04-16 03:17:093039 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273040
[email protected]2d2697f92009-02-18 21:00:323041 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163042 MockWrite("GET / HTTP/1.1\r\n"
3043 "Host: www.example.org\r\n"
3044 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323045
bnc691fda62016-08-12 00:43:163046 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233047 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163048 MockWrite("GET / HTTP/1.1\r\n"
3049 "Host: www.example.org\r\n"
3050 "Connection: keep-alive\r\n"
3051 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323052 };
3053
[email protected]2d2697f92009-02-18 21:00:323054 MockRead data_reads1[] = {
3055 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3056 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:313057 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:323058
3059 // Lastly, the server responds with the actual content.
3060 MockRead("HTTP/1.1 200 OK\r\n"),
3061 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503062 MockRead("Content-Length: 5\r\n\r\n"),
3063 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323064 };
3065
[email protected]2d0a4f92011-05-05 16:38:463066 // An incorrect reconnect would cause this to be read.
3067 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063068 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463069 };
3070
Ryan Sleevib8d7ea02018-05-07 20:01:013071 StaticSocketDataProvider data1(data_reads1, data_writes1);
3072 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073073 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3074 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323075
[email protected]49639fa2011-12-20 23:22:413076 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323077
bnc691fda62016-08-12 00:43:163078 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203079 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323081
3082 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013083 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323084
bnc691fda62016-08-12 00:43:163085 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523086 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583087 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]2d2697f92009-02-18 21:00:323088
[email protected]49639fa2011-12-20 23:22:413089 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323090
bnc691fda62016-08-12 00:43:163091 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013092 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323093
3094 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013095 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323096
bnc691fda62016-08-12 00:43:163097 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523098 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583099 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0b0bf032010-09-21 18:08:503100 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323101}
3102
3103// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3104// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:013105TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:423106 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323107 request.method = "GET";
bncce36dca22015-04-21 22:11:233108 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103109 request.traffic_annotation =
3110 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323111
danakj1fd259a02016-04-16 03:17:093112 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273113
[email protected]2d2697f92009-02-18 21:00:323114 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163115 MockWrite("GET / HTTP/1.1\r\n"
3116 "Host: www.example.org\r\n"
3117 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323118
bnc691fda62016-08-12 00:43:163119 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233120 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163121 MockWrite("GET / HTTP/1.1\r\n"
3122 "Host: www.example.org\r\n"
3123 "Connection: keep-alive\r\n"
3124 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323125 };
3126
3127 // Respond with 5 kb of response body.
3128 std::string large_body_string("Unauthorized");
3129 large_body_string.append(5 * 1024, ' ');
3130 large_body_string.append("\r\n");
3131
3132 MockRead data_reads1[] = {
3133 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3134 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3135 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3136 // 5134 = 12 + 5 * 1024 + 2
3137 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063138 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:323139
3140 // Lastly, the server responds with the actual content.
3141 MockRead("HTTP/1.1 200 OK\r\n"),
3142 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503143 MockRead("Content-Length: 5\r\n\r\n"),
3144 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323145 };
3146
[email protected]2d0a4f92011-05-05 16:38:463147 // An incorrect reconnect would cause this to be read.
3148 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063149 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463150 };
3151
Ryan Sleevib8d7ea02018-05-07 20:01:013152 StaticSocketDataProvider data1(data_reads1, data_writes1);
3153 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073154 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3155 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323156
[email protected]49639fa2011-12-20 23:22:413157 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323158
bnc691fda62016-08-12 00:43:163159 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203160 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013161 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323162
3163 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013164 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323165
bnc691fda62016-08-12 00:43:163166 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523167 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583168 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]2d2697f92009-02-18 21:00:323169
[email protected]49639fa2011-12-20 23:22:413170 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323171
bnc691fda62016-08-12 00:43:163172 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013173 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323174
3175 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013176 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323177
bnc691fda62016-08-12 00:43:163178 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523179 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583180 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0b0bf032010-09-21 18:08:503181 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323182}
3183
3184// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:313185// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:013186TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:313187 HttpRequestInfo request;
3188 request.method = "GET";
bncce36dca22015-04-21 22:11:233189 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103190 request.traffic_annotation =
3191 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313192
danakj1fd259a02016-04-16 03:17:093193 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273194
[email protected]11203f012009-11-12 23:02:313195 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233196 MockWrite(
3197 "GET / HTTP/1.1\r\n"
3198 "Host: www.example.org\r\n"
3199 "Connection: keep-alive\r\n\r\n"),
3200 // This simulates the seemingly successful write to a closed connection
3201 // if the bug is not fixed.
3202 MockWrite(
3203 "GET / HTTP/1.1\r\n"
3204 "Host: www.example.org\r\n"
3205 "Connection: keep-alive\r\n"
3206 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313207 };
3208
3209 MockRead data_reads1[] = {
3210 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3211 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3212 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3213 MockRead("Content-Length: 14\r\n\r\n"),
3214 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063215 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313216 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063217 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313218 };
3219
bnc691fda62016-08-12 00:43:163220 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313221 // be issuing -- the final header line contains the credentials.
3222 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233223 MockWrite(
3224 "GET / HTTP/1.1\r\n"
3225 "Host: www.example.org\r\n"
3226 "Connection: keep-alive\r\n"
3227 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313228 };
3229
3230 // Lastly, the server responds with the actual content.
3231 MockRead data_reads2[] = {
3232 MockRead("HTTP/1.1 200 OK\r\n"),
3233 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503234 MockRead("Content-Length: 5\r\n\r\n"),
3235 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313236 };
3237
Ryan Sleevib8d7ea02018-05-07 20:01:013238 StaticSocketDataProvider data1(data_reads1, data_writes1);
3239 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:073240 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3241 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313242
[email protected]49639fa2011-12-20 23:22:413243 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313244
bnc691fda62016-08-12 00:43:163245 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203246 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013247 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313248
3249 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013250 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313251
bnc691fda62016-08-12 00:43:163252 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523253 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583254 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]11203f012009-11-12 23:02:313255
[email protected]49639fa2011-12-20 23:22:413256 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313257
bnc691fda62016-08-12 00:43:163258 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013259 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313260
3261 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013262 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313263
bnc691fda62016-08-12 00:43:163264 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523265 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583266 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0b0bf032010-09-21 18:08:503267 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313268}
3269
[email protected]394816e92010-08-03 07:38:593270// Test the request-challenge-retry sequence for basic auth, over a connection
3271// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013272TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013273 HttpRequestInfo request;
3274 request.method = "GET";
bncce36dca22015-04-21 22:11:233275 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013276 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293277 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103278 request.traffic_annotation =
3279 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013280
3281 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593282 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493283 ProxyResolutionService::CreateFixedFromPacResult(
3284 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513285 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013286 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093287 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013288
3289 // Since we have proxy, should try to establish tunnel.
3290 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543291 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173292 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543293 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013294 };
3295
mmenkee71e15332015-10-07 16:39:543296 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013297 // connection.
3298 MockRead data_reads1[] = {
3299 // No credentials.
3300 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3301 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543302 };
ttuttle34f63b52015-03-05 04:33:013303
mmenkee71e15332015-10-07 16:39:543304 // Since the first connection couldn't be reused, need to establish another
3305 // once given credentials.
3306 MockWrite data_writes2[] = {
3307 // After calling trans->RestartWithAuth(), this is the request we should
3308 // be issuing -- the final header line contains the credentials.
3309 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173310 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543311 "Proxy-Connection: keep-alive\r\n"
3312 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3313
3314 MockWrite("GET / HTTP/1.1\r\n"
3315 "Host: www.example.org\r\n"
3316 "Connection: keep-alive\r\n\r\n"),
3317 };
3318
3319 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013320 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3321
3322 MockRead("HTTP/1.1 200 OK\r\n"),
3323 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3324 MockRead("Content-Length: 5\r\n\r\n"),
3325 MockRead(SYNCHRONOUS, "hello"),
3326 };
3327
Ryan Sleevib8d7ea02018-05-07 20:01:013328 StaticSocketDataProvider data1(data_reads1, data_writes1);
ttuttle34f63b52015-03-05 04:33:013329 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013330 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543331 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013332 SSLSocketDataProvider ssl(ASYNC, OK);
3333 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3334
3335 TestCompletionCallback callback1;
3336
bnc87dcefc2017-05-25 12:47:583337 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193338 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013339
3340 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013341 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013342
3343 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013344 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463345 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013346 log.GetEntries(&entries);
3347 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003348 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3349 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013350 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003351 entries, pos,
3352 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3353 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013354
3355 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523356 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013357 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523358 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013359 EXPECT_EQ(407, response->headers->response_code());
3360 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583361 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
ttuttle34f63b52015-03-05 04:33:013362
3363 LoadTimingInfo load_timing_info;
3364 // CONNECT requests and responses are handled at the connect job level, so
3365 // the transaction does not yet have a connection.
3366 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3367
3368 TestCompletionCallback callback2;
3369
3370 rv =
3371 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013372 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013373
3374 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013375 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013376
3377 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523378 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013379
3380 EXPECT_TRUE(response->headers->IsKeepAlive());
3381 EXPECT_EQ(200, response->headers->response_code());
3382 EXPECT_EQ(5, response->headers->GetContentLength());
3383 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3384
3385 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:583386 EXPECT_FALSE(response->auth_challenge.has_value());
ttuttle34f63b52015-03-05 04:33:013387
3388 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3389 TestLoadTimingNotReusedWithPac(load_timing_info,
3390 CONNECT_TIMING_HAS_SSL_TIMES);
3391
3392 trans.reset();
3393 session->CloseAllConnections();
3394}
3395
3396// Test the request-challenge-retry sequence for basic auth, over a connection
3397// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013398TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593399 HttpRequestInfo request;
3400 request.method = "GET";
bncce36dca22015-04-21 22:11:233401 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593402 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293403 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103404 request.traffic_annotation =
3405 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593406
[email protected]cb9bf6ca2011-01-28 13:15:273407 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593408 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493409 ProxyResolutionService::CreateFixedFromPacResult(
3410 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513411 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073412 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093413 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273414
[email protected]394816e92010-08-03 07:38:593415 // Since we have proxy, should try to establish tunnel.
3416 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543417 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173418 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543419 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113420 };
3421
mmenkee71e15332015-10-07 16:39:543422 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083423 // connection.
3424 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543425 // No credentials.
3426 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3427 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3428 MockRead("Proxy-Connection: close\r\n\r\n"),
3429 };
mmenkee0b5c882015-08-26 20:29:113430
mmenkee71e15332015-10-07 16:39:543431 MockWrite data_writes2[] = {
3432 // After calling trans->RestartWithAuth(), this is the request we should
3433 // be issuing -- the final header line contains the credentials.
3434 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173435 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543436 "Proxy-Connection: keep-alive\r\n"
3437 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083438
mmenkee71e15332015-10-07 16:39:543439 MockWrite("GET / HTTP/1.1\r\n"
3440 "Host: www.example.org\r\n"
3441 "Connection: keep-alive\r\n\r\n"),
3442 };
3443
3444 MockRead data_reads2[] = {
3445 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3446
3447 MockRead("HTTP/1.1 200 OK\r\n"),
3448 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3449 MockRead("Content-Length: 5\r\n\r\n"),
3450 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593451 };
3452
Ryan Sleevib8d7ea02018-05-07 20:01:013453 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073454 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013455 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543456 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063457 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073458 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593459
[email protected]49639fa2011-12-20 23:22:413460 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593461
bnc87dcefc2017-05-25 12:47:583462 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193463 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503464
[email protected]49639fa2011-12-20 23:22:413465 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013466 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593467
3468 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013469 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463470 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403471 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593472 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003473 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3474 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593475 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403476 entries, pos,
mikecirone8b85c432016-09-08 19:11:003477 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3478 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593479
3480 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523481 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013482 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523483 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593484 EXPECT_EQ(407, response->headers->response_code());
3485 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583486 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
[email protected]394816e92010-08-03 07:38:593487
[email protected]029c83b62013-01-24 05:28:203488 LoadTimingInfo load_timing_info;
3489 // CONNECT requests and responses are handled at the connect job level, so
3490 // the transaction does not yet have a connection.
3491 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3492
[email protected]49639fa2011-12-20 23:22:413493 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593494
[email protected]49639fa2011-12-20 23:22:413495 rv = trans->RestartWithAuth(
3496 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013497 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593498
3499 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013500 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593501
3502 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523503 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593504
3505 EXPECT_TRUE(response->headers->IsKeepAlive());
3506 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503507 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593508 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3509
3510 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:583511 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0b0bf032010-09-21 18:08:503512
[email protected]029c83b62013-01-24 05:28:203513 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3514 TestLoadTimingNotReusedWithPac(load_timing_info,
3515 CONNECT_TIMING_HAS_SSL_TIMES);
3516
[email protected]0b0bf032010-09-21 18:08:503517 trans.reset();
[email protected]102e27c2011-02-23 01:01:313518 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593519}
3520
[email protected]11203f012009-11-12 23:02:313521// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013522// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013523TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233524 // On the second pass, the body read of the auth challenge is synchronous, so
3525 // IsConnectedAndIdle returns false. The socket should still be drained and
3526 // reused. See http://crbug.com/544255.
3527 for (int i = 0; i < 2; ++i) {
3528 HttpRequestInfo request;
3529 request.method = "GET";
3530 request.url = GURL("https://www.example.org/");
3531 // Ensure that proxy authentication is attempted even
3532 // when the no authentication data flag is set.
3533 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103534 request.traffic_annotation =
3535 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013536
mmenked39192ee2015-12-09 00:57:233537 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593538 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493539 ProxyResolutionService::CreateFixed("myproxy:70",
3540 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233541 BoundTestNetLog log;
3542 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093543 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013544
bnc691fda62016-08-12 00:43:163545 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013546
mmenked39192ee2015-12-09 00:57:233547 // Since we have proxy, should try to establish tunnel.
3548 MockWrite data_writes1[] = {
3549 MockWrite(ASYNC, 0,
3550 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3551 "Host: www.example.org:443\r\n"
3552 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013553
bnc691fda62016-08-12 00:43:163554 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233555 // be issuing -- the final header line contains the credentials.
3556 MockWrite(ASYNC, 3,
3557 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3558 "Host: www.example.org:443\r\n"
3559 "Proxy-Connection: keep-alive\r\n"
3560 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3561 };
ttuttle34f63b52015-03-05 04:33:013562
mmenked39192ee2015-12-09 00:57:233563 // The proxy responds to the connect with a 407, using a persistent
3564 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3565 MockRead data_reads1[] = {
3566 // No credentials.
3567 MockRead(ASYNC, 1,
3568 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3569 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3570 "Proxy-Connection: keep-alive\r\n"
3571 "Content-Length: 10\r\n\r\n"),
3572 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013573
mmenked39192ee2015-12-09 00:57:233574 // Wrong credentials (wrong password).
3575 MockRead(ASYNC, 4,
3576 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3577 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3578 "Proxy-Connection: keep-alive\r\n"
3579 "Content-Length: 10\r\n\r\n"),
3580 // No response body because the test stops reading here.
3581 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3582 };
ttuttle34f63b52015-03-05 04:33:013583
Ryan Sleevib8d7ea02018-05-07 20:01:013584 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233585 data1.set_busy_before_sync_reads(true);
3586 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013587
mmenked39192ee2015-12-09 00:57:233588 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013589
bnc691fda62016-08-12 00:43:163590 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013591 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013592
mmenked39192ee2015-12-09 00:57:233593 TestNetLogEntry::List entries;
3594 log.GetEntries(&entries);
3595 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003596 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3597 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233598 ExpectLogContainsSomewhere(
3599 entries, pos,
mikecirone8b85c432016-09-08 19:11:003600 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3601 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013602
bnc691fda62016-08-12 00:43:163603 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233604 ASSERT_TRUE(response);
3605 ASSERT_TRUE(response->headers);
3606 EXPECT_TRUE(response->headers->IsKeepAlive());
3607 EXPECT_EQ(407, response->headers->response_code());
3608 EXPECT_EQ(10, response->headers->GetContentLength());
3609 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583610 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
ttuttle34f63b52015-03-05 04:33:013611
mmenked39192ee2015-12-09 00:57:233612 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013613
mmenked39192ee2015-12-09 00:57:233614 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163615 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3616 callback2.callback());
robpercival214763f2016-07-01 23:27:013617 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013618
bnc691fda62016-08-12 00:43:163619 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233620 ASSERT_TRUE(response);
3621 ASSERT_TRUE(response->headers);
3622 EXPECT_TRUE(response->headers->IsKeepAlive());
3623 EXPECT_EQ(407, response->headers->response_code());
3624 EXPECT_EQ(10, response->headers->GetContentLength());
3625 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583626 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
ttuttle34f63b52015-03-05 04:33:013627
mmenked39192ee2015-12-09 00:57:233628 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3629 // out of scope.
3630 session->CloseAllConnections();
3631 }
ttuttle34f63b52015-03-05 04:33:013632}
3633
3634// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3635// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013636TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233637 // On the second pass, the body read of the auth challenge is synchronous, so
3638 // IsConnectedAndIdle returns false. The socket should still be drained and
3639 // reused. See http://crbug.com/544255.
3640 for (int i = 0; i < 2; ++i) {
3641 HttpRequestInfo request;
3642 request.method = "GET";
3643 request.url = GURL("https://www.example.org/");
3644 // Ensure that proxy authentication is attempted even
3645 // when the no authentication data flag is set.
3646 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103647 request.traffic_annotation =
3648 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233649
3650 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593651 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493652 ProxyResolutionService::CreateFixed("myproxy:70",
3653 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233654 BoundTestNetLog log;
3655 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093656 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233657
bnc691fda62016-08-12 00:43:163658 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233659
3660 // Since we have proxy, should try to establish tunnel.
3661 MockWrite data_writes1[] = {
3662 MockWrite(ASYNC, 0,
3663 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3664 "Host: www.example.org:443\r\n"
3665 "Proxy-Connection: keep-alive\r\n\r\n"),
3666
bnc691fda62016-08-12 00:43:163667 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233668 // be issuing -- the final header line contains the credentials.
3669 MockWrite(ASYNC, 3,
3670 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3671 "Host: www.example.org:443\r\n"
3672 "Proxy-Connection: keep-alive\r\n"
3673 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3674 };
3675
3676 // The proxy responds to the connect with a 407, using a persistent
3677 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3678 MockRead data_reads1[] = {
3679 // No credentials.
3680 MockRead(ASYNC, 1,
3681 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3682 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3683 "Content-Length: 10\r\n\r\n"),
3684 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3685
3686 // Wrong credentials (wrong password).
3687 MockRead(ASYNC, 4,
3688 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3689 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3690 "Content-Length: 10\r\n\r\n"),
3691 // No response body because the test stops reading here.
3692 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3693 };
3694
Ryan Sleevib8d7ea02018-05-07 20:01:013695 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233696 data1.set_busy_before_sync_reads(true);
3697 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3698
3699 TestCompletionCallback callback1;
3700
bnc691fda62016-08-12 00:43:163701 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013702 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233703
3704 TestNetLogEntry::List entries;
3705 log.GetEntries(&entries);
3706 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003707 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3708 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233709 ExpectLogContainsSomewhere(
3710 entries, pos,
mikecirone8b85c432016-09-08 19:11:003711 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3712 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233713
bnc691fda62016-08-12 00:43:163714 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233715 ASSERT_TRUE(response);
3716 ASSERT_TRUE(response->headers);
3717 EXPECT_TRUE(response->headers->IsKeepAlive());
3718 EXPECT_EQ(407, response->headers->response_code());
3719 EXPECT_EQ(10, response->headers->GetContentLength());
3720 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583721 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
Wojciech Dzierżanowski0950c372019-04-02 19:29:503722 EXPECT_FALSE(response->did_use_http_auth);
mmenked39192ee2015-12-09 00:57:233723
3724 TestCompletionCallback callback2;
3725
3726 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163727 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3728 callback2.callback());
robpercival214763f2016-07-01 23:27:013729 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233730
bnc691fda62016-08-12 00:43:163731 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233732 ASSERT_TRUE(response);
3733 ASSERT_TRUE(response->headers);
3734 EXPECT_TRUE(response->headers->IsKeepAlive());
3735 EXPECT_EQ(407, response->headers->response_code());
3736 EXPECT_EQ(10, response->headers->GetContentLength());
3737 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583738 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
Wojciech Dzierżanowski0950c372019-04-02 19:29:503739 EXPECT_TRUE(response->did_use_http_auth);
mmenked39192ee2015-12-09 00:57:233740
3741 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3742 // out of scope.
3743 session->CloseAllConnections();
3744 }
3745}
3746
3747// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3748// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3749// the case the server sends extra data on the original socket, so it can't be
3750// reused.
bncd16676a2016-07-20 16:23:013751TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273752 HttpRequestInfo request;
3753 request.method = "GET";
bncce36dca22015-04-21 22:11:233754 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273755 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293756 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103757 request.traffic_annotation =
3758 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273759
[email protected]2d2697f92009-02-18 21:00:323760 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593761 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493762 ProxyResolutionService::CreateFixedFromPacResult(
3763 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513764 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073765 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323767
[email protected]2d2697f92009-02-18 21:00:323768 // Since we have proxy, should try to establish tunnel.
3769 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233770 MockWrite(ASYNC, 0,
3771 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173772 "Host: www.example.org:443\r\n"
3773 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233774 };
[email protected]2d2697f92009-02-18 21:00:323775
mmenked39192ee2015-12-09 00:57:233776 // The proxy responds to the connect with a 407, using a persistent, but sends
3777 // extra data, so the socket cannot be reused.
3778 MockRead data_reads1[] = {
3779 // No credentials.
3780 MockRead(ASYNC, 1,
3781 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3782 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3783 "Content-Length: 10\r\n\r\n"),
3784 MockRead(SYNCHRONOUS, 2, "0123456789"),
3785 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3786 };
3787
3788 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233789 // After calling trans->RestartWithAuth(), this is the request we should
3790 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233791 MockWrite(ASYNC, 0,
3792 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173793 "Host: www.example.org:443\r\n"
3794 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233795 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3796
3797 MockWrite(ASYNC, 2,
3798 "GET / HTTP/1.1\r\n"
3799 "Host: www.example.org\r\n"
3800 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323801 };
3802
mmenked39192ee2015-12-09 00:57:233803 MockRead data_reads2[] = {
3804 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323805
mmenked39192ee2015-12-09 00:57:233806 MockRead(ASYNC, 3,
3807 "HTTP/1.1 200 OK\r\n"
3808 "Content-Type: text/html; charset=iso-8859-1\r\n"
3809 "Content-Length: 5\r\n\r\n"),
3810 // No response body because the test stops reading here.
3811 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323812 };
3813
Ryan Sleevib8d7ea02018-05-07 20:01:013814 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233815 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073816 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013817 SequencedSocketData data2(data_reads2, data_writes2);
mmenked39192ee2015-12-09 00:57:233818 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3819 SSLSocketDataProvider ssl(ASYNC, OK);
3820 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323821
[email protected]49639fa2011-12-20 23:22:413822 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323823
bnc87dcefc2017-05-25 12:47:583824 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193825 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323826
mmenked39192ee2015-12-09 00:57:233827 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013828 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233829
mmenke43758e62015-05-04 21:09:463830 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403831 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393832 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003833 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3834 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393835 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403836 entries, pos,
mikecirone8b85c432016-09-08 19:11:003837 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3838 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323839
[email protected]1c773ea12009-04-28 19:58:423840 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243841 ASSERT_TRUE(response);
3842 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323843 EXPECT_TRUE(response->headers->IsKeepAlive());
3844 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423845 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583846 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
[email protected]2d2697f92009-02-18 21:00:323847
mmenked39192ee2015-12-09 00:57:233848 LoadTimingInfo load_timing_info;
3849 // CONNECT requests and responses are handled at the connect job level, so
3850 // the transaction does not yet have a connection.
3851 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3852
[email protected]49639fa2011-12-20 23:22:413853 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323854
mmenked39192ee2015-12-09 00:57:233855 rv =
3856 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013857 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323858
[email protected]2d2697f92009-02-18 21:00:323859 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233860 EXPECT_EQ(200, response->headers->response_code());
3861 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423862 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133863
mmenked39192ee2015-12-09 00:57:233864 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:583865 EXPECT_FALSE(response->auth_challenge.has_value());
mmenked39192ee2015-12-09 00:57:233866
3867 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3868 TestLoadTimingNotReusedWithPac(load_timing_info,
3869 CONNECT_TIMING_HAS_SSL_TIMES);
3870
3871 trans.reset();
[email protected]102e27c2011-02-23 01:01:313872 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323873}
3874
mmenkee71e15332015-10-07 16:39:543875// Test the case a proxy closes a socket while the challenge body is being
3876// drained.
bncd16676a2016-07-20 16:23:013877TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543878 HttpRequestInfo request;
3879 request.method = "GET";
3880 request.url = GURL("https://www.example.org/");
3881 // Ensure that proxy authentication is attempted even
3882 // when the no authentication data flag is set.
3883 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103884 request.traffic_annotation =
3885 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543886
3887 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493888 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3889 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093890 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543891
bnc691fda62016-08-12 00:43:163892 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543893
3894 // Since we have proxy, should try to establish tunnel.
3895 MockWrite data_writes1[] = {
3896 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173897 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543898 "Proxy-Connection: keep-alive\r\n\r\n"),
3899 };
3900
3901 // The proxy responds to the connect with a 407, using a persistent
3902 // connection.
3903 MockRead data_reads1[] = {
3904 // No credentials.
3905 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3906 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3907 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3908 // Server hands up in the middle of the body.
3909 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3910 };
3911
3912 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163913 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543914 // be issuing -- the final header line contains the credentials.
3915 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173916 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543917 "Proxy-Connection: keep-alive\r\n"
3918 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3919
3920 MockWrite("GET / HTTP/1.1\r\n"
3921 "Host: www.example.org\r\n"
3922 "Connection: keep-alive\r\n\r\n"),
3923 };
3924
3925 MockRead data_reads2[] = {
3926 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3927
3928 MockRead("HTTP/1.1 200 OK\r\n"),
3929 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3930 MockRead("Content-Length: 5\r\n\r\n"),
3931 MockRead(SYNCHRONOUS, "hello"),
3932 };
3933
Ryan Sleevib8d7ea02018-05-07 20:01:013934 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenkee71e15332015-10-07 16:39:543935 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013936 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543937 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3938 SSLSocketDataProvider ssl(ASYNC, OK);
3939 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3940
3941 TestCompletionCallback callback;
3942
tfarina42834112016-09-22 13:38:203943 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013944 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543945
bnc691fda62016-08-12 00:43:163946 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543947 ASSERT_TRUE(response);
3948 ASSERT_TRUE(response->headers);
3949 EXPECT_TRUE(response->headers->IsKeepAlive());
3950 EXPECT_EQ(407, response->headers->response_code());
Emily Starkf2c9bbd2019-04-09 17:08:583951 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
mmenkee71e15332015-10-07 16:39:543952
bnc691fda62016-08-12 00:43:163953 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013954 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543955
bnc691fda62016-08-12 00:43:163956 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543957 ASSERT_TRUE(response);
3958 ASSERT_TRUE(response->headers);
3959 EXPECT_TRUE(response->headers->IsKeepAlive());
3960 EXPECT_EQ(200, response->headers->response_code());
3961 std::string body;
bnc691fda62016-08-12 00:43:163962 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543963 EXPECT_EQ("hello", body);
3964}
3965
[email protected]a8e9b162009-03-12 00:06:443966// Test that we don't read the response body when we fail to establish a tunnel,
3967// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013968TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273969 HttpRequestInfo request;
3970 request.method = "GET";
bncce36dca22015-04-21 22:11:233971 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103972 request.traffic_annotation =
3973 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273974
[email protected]a8e9b162009-03-12 00:06:443975 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493976 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3977 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443978
danakj1fd259a02016-04-16 03:17:093979 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443980
bnc691fda62016-08-12 00:43:163981 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443982
[email protected]a8e9b162009-03-12 00:06:443983 // Since we have proxy, should try to establish tunnel.
3984 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173985 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3986 "Host: www.example.org:443\r\n"
3987 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443988 };
3989
3990 // The proxy responds to the connect with a 407.
3991 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243992 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3993 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3994 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233995 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243996 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443997 };
3998
Ryan Sleevib8d7ea02018-05-07 20:01:013999 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:074000 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:444001
[email protected]49639fa2011-12-20 23:22:414002 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:444003
tfarina42834112016-09-22 13:38:204004 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014005 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:444006
4007 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014008 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:444009
bnc691fda62016-08-12 00:43:164010 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244011 ASSERT_TRUE(response);
4012 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:444013 EXPECT_TRUE(response->headers->IsKeepAlive());
4014 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:424015 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:444016
4017 std::string response_data;
bnc691fda62016-08-12 00:43:164018 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014019 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:184020
4021 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:314022 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:444023}
4024
ttuttle7933c112015-01-06 00:55:244025// Test that we don't pass extraneous headers from the proxy's response to the
4026// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:014027TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:244028 HttpRequestInfo request;
4029 request.method = "GET";
bncce36dca22015-04-21 22:11:234030 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104031 request.traffic_annotation =
4032 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244033
4034 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494035 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4036 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244037
danakj1fd259a02016-04-16 03:17:094038 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:244039
bnc691fda62016-08-12 00:43:164040 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:244041
4042 // Since we have proxy, should try to establish tunnel.
4043 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:174044 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4045 "Host: www.example.org:443\r\n"
4046 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:244047 };
4048
4049 // The proxy responds to the connect with a 407.
4050 MockRead data_reads[] = {
4051 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4052 MockRead("X-Foo: bar\r\n"),
4053 MockRead("Set-Cookie: foo=bar\r\n"),
4054 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4055 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:234056 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:244057 };
4058
Ryan Sleevib8d7ea02018-05-07 20:01:014059 StaticSocketDataProvider data(data_reads, data_writes);
ttuttle7933c112015-01-06 00:55:244060 session_deps_.socket_factory->AddSocketDataProvider(&data);
4061
4062 TestCompletionCallback callback;
4063
tfarina42834112016-09-22 13:38:204064 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014065 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:244066
4067 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014068 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:244069
bnc691fda62016-08-12 00:43:164070 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244071 ASSERT_TRUE(response);
4072 ASSERT_TRUE(response->headers);
4073 EXPECT_TRUE(response->headers->IsKeepAlive());
4074 EXPECT_EQ(407, response->headers->response_code());
4075 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4076 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
4077 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
4078
4079 std::string response_data;
bnc691fda62016-08-12 00:43:164080 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014081 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:244082
4083 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
4084 session->CloseAllConnections();
4085}
4086
[email protected]8fdbcd22010-05-05 02:54:524087// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
4088// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:014089TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:524090 HttpRequestInfo request;
4091 request.method = "GET";
bncce36dca22015-04-21 22:11:234092 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104093 request.traffic_annotation =
4094 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:524095
[email protected]cb9bf6ca2011-01-28 13:15:274096 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:094097 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:164098 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:274099
[email protected]8fdbcd22010-05-05 02:54:524100 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234101 MockWrite(
4102 "GET / HTTP/1.1\r\n"
4103 "Host: www.example.org\r\n"
4104 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:524105 };
4106
4107 MockRead data_reads1[] = {
4108 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
4109 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4110 // Large content-length -- won't matter, as connection will be reset.
4111 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064112 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:524113 };
4114
Ryan Sleevib8d7ea02018-05-07 20:01:014115 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074116 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:524117
[email protected]49639fa2011-12-20 23:22:414118 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:524119
tfarina42834112016-09-22 13:38:204120 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014121 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:524122
4123 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014124 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:524125}
4126
[email protected]7a67a8152010-11-05 18:31:104127// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
4128// through a non-authenticating proxy. The request should fail with
4129// ERR_UNEXPECTED_PROXY_AUTH.
4130// Note that it is impossible to detect if an HTTP server returns a 407 through
4131// a non-authenticating proxy - there is nothing to indicate whether the
4132// response came from the proxy or the server, so it is treated as if the proxy
4133// issued the challenge.
bncd16676a2016-07-20 16:23:014134TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:274135 HttpRequestInfo request;
4136 request.method = "GET";
bncce36dca22015-04-21 22:11:234137 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104138 request.traffic_annotation =
4139 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274140
Ramin Halavatica8d5252018-03-12 05:33:494141 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4142 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514143 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074144 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094145 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:104146
[email protected]7a67a8152010-11-05 18:31:104147 // Since we have proxy, should try to establish tunnel.
4148 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174149 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4150 "Host: www.example.org:443\r\n"
4151 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104152
rsleevidb16bb02015-11-12 23:47:174153 MockWrite("GET / HTTP/1.1\r\n"
4154 "Host: www.example.org\r\n"
4155 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104156 };
4157
4158 MockRead data_reads1[] = {
4159 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4160
4161 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
4162 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4163 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:064164 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:104165 };
4166
Ryan Sleevib8d7ea02018-05-07 20:01:014167 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074168 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064169 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074170 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:104171
[email protected]49639fa2011-12-20 23:22:414172 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:104173
bnc691fda62016-08-12 00:43:164174 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:104175
bnc691fda62016-08-12 00:43:164176 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014177 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:104178
4179 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014180 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464181 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404182 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104183 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004184 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4185 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104186 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404187 entries, pos,
mikecirone8b85c432016-09-08 19:11:004188 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4189 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104190}
[email protected]2df19bb2010-08-25 20:13:464191
mmenke2a1781d2015-10-07 19:25:334192// Test a proxy auth scheme that allows default credentials and a proxy server
4193// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014194TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334195 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4196 HttpRequestInfo request;
4197 request.method = "GET";
4198 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104199 request.traffic_annotation =
4200 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334201
4202 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594203 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494204 ProxyResolutionService::CreateFixedFromPacResult(
4205 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334206
Jeremy Roman0579ed62017-08-29 15:56:194207 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334208 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194209 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334210 mock_handler->set_allows_default_credentials(true);
4211 auth_handler_factory->AddMockHandler(mock_handler.release(),
4212 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484213 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334214
4215 // Add NetLog just so can verify load timing information gets a NetLog ID.
4216 NetLog net_log;
4217 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094218 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334219
4220 // Since we have proxy, should try to establish tunnel.
4221 MockWrite data_writes1[] = {
4222 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174223 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334224 "Proxy-Connection: keep-alive\r\n\r\n"),
4225 };
4226
4227 // The proxy responds to the connect with a 407, using a non-persistent
4228 // connection.
4229 MockRead data_reads1[] = {
4230 // No credentials.
4231 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4232 MockRead("Proxy-Authenticate: Mock\r\n"),
4233 MockRead("Proxy-Connection: close\r\n\r\n"),
4234 };
4235
4236 // Since the first connection couldn't be reused, need to establish another
4237 // once given credentials.
4238 MockWrite data_writes2[] = {
4239 // After calling trans->RestartWithAuth(), this is the request we should
4240 // be issuing -- the final header line contains the credentials.
4241 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174242 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334243 "Proxy-Connection: keep-alive\r\n"
4244 "Proxy-Authorization: auth_token\r\n\r\n"),
4245
4246 MockWrite("GET / HTTP/1.1\r\n"
4247 "Host: www.example.org\r\n"
4248 "Connection: keep-alive\r\n\r\n"),
4249 };
4250
4251 MockRead data_reads2[] = {
4252 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4253
4254 MockRead("HTTP/1.1 200 OK\r\n"),
4255 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4256 MockRead("Content-Length: 5\r\n\r\n"),
4257 MockRead(SYNCHRONOUS, "hello"),
4258 };
4259
Ryan Sleevib8d7ea02018-05-07 20:01:014260 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334261 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014262 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334263 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4264 SSLSocketDataProvider ssl(ASYNC, OK);
4265 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4266
bnc87dcefc2017-05-25 12:47:584267 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194268 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334269
4270 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204271 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014272 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334273
4274 const HttpResponseInfo* response = trans->GetResponseInfo();
4275 ASSERT_TRUE(response);
4276 ASSERT_TRUE(response->headers);
4277 EXPECT_FALSE(response->headers->IsKeepAlive());
4278 EXPECT_EQ(407, response->headers->response_code());
4279 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4280 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584281 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334282
4283 LoadTimingInfo load_timing_info;
4284 // CONNECT requests and responses are handled at the connect job level, so
4285 // the transaction does not yet have a connection.
4286 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4287
4288 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014289 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334290 response = trans->GetResponseInfo();
4291 ASSERT_TRUE(response);
4292 ASSERT_TRUE(response->headers);
4293 EXPECT_TRUE(response->headers->IsKeepAlive());
4294 EXPECT_EQ(200, response->headers->response_code());
4295 EXPECT_EQ(5, response->headers->GetContentLength());
4296 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4297
4298 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:584299 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334300
4301 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4302 TestLoadTimingNotReusedWithPac(load_timing_info,
4303 CONNECT_TIMING_HAS_SSL_TIMES);
4304
4305 trans.reset();
4306 session->CloseAllConnections();
4307}
4308
4309// Test a proxy auth scheme that allows default credentials and a proxy server
4310// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014311TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334312 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4313 HttpRequestInfo request;
4314 request.method = "GET";
4315 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104316 request.traffic_annotation =
4317 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334318
4319 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594320 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494321 ProxyResolutionService::CreateFixedFromPacResult(
4322 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334323
Jeremy Roman0579ed62017-08-29 15:56:194324 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334325 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194326 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334327 mock_handler->set_allows_default_credentials(true);
4328 auth_handler_factory->AddMockHandler(mock_handler.release(),
4329 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484330 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334331
4332 // Add NetLog just so can verify load timing information gets a NetLog ID.
4333 NetLog net_log;
4334 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094335 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334336
4337 // Should try to establish tunnel.
4338 MockWrite data_writes1[] = {
4339 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174340 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334341 "Proxy-Connection: keep-alive\r\n\r\n"),
4342
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"
4346 "Proxy-Authorization: auth_token\r\n\r\n"),
4347 };
4348
4349 // The proxy responds to the connect with a 407, using a non-persistent
4350 // connection.
4351 MockRead data_reads1[] = {
4352 // No credentials.
4353 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4354 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4355 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4356 };
4357
4358 // Since the first connection was closed, need to establish another once given
4359 // credentials.
4360 MockWrite data_writes2[] = {
4361 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174362 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334363 "Proxy-Connection: keep-alive\r\n"
4364 "Proxy-Authorization: auth_token\r\n\r\n"),
4365
4366 MockWrite("GET / HTTP/1.1\r\n"
4367 "Host: www.example.org\r\n"
4368 "Connection: keep-alive\r\n\r\n"),
4369 };
4370
4371 MockRead data_reads2[] = {
4372 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4373
4374 MockRead("HTTP/1.1 200 OK\r\n"),
4375 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4376 MockRead("Content-Length: 5\r\n\r\n"),
4377 MockRead(SYNCHRONOUS, "hello"),
4378 };
4379
Ryan Sleevib8d7ea02018-05-07 20:01:014380 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334381 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014382 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334383 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4384 SSLSocketDataProvider ssl(ASYNC, OK);
4385 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4386
bnc87dcefc2017-05-25 12:47:584387 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194388 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334389
4390 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204391 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014392 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334393
4394 const HttpResponseInfo* response = trans->GetResponseInfo();
4395 ASSERT_TRUE(response);
4396 ASSERT_TRUE(response->headers);
4397 EXPECT_TRUE(response->headers->IsKeepAlive());
4398 EXPECT_EQ(407, response->headers->response_code());
4399 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4400 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584401 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334402
4403 LoadTimingInfo load_timing_info;
4404 // CONNECT requests and responses are handled at the connect job level, so
4405 // the transaction does not yet have a connection.
4406 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4407
4408 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014409 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334410
4411 response = trans->GetResponseInfo();
4412 ASSERT_TRUE(response);
4413 ASSERT_TRUE(response->headers);
4414 EXPECT_TRUE(response->headers->IsKeepAlive());
4415 EXPECT_EQ(200, response->headers->response_code());
4416 EXPECT_EQ(5, response->headers->GetContentLength());
4417 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4418
4419 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:584420 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334421
4422 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4423 TestLoadTimingNotReusedWithPac(load_timing_info,
4424 CONNECT_TIMING_HAS_SSL_TIMES);
4425
4426 trans.reset();
4427 session->CloseAllConnections();
4428}
4429
4430// Test a proxy auth scheme that allows default credentials and a proxy server
4431// that hangs up when credentials are initially sent, and hangs up again when
4432// they are retried.
bncd16676a2016-07-20 16:23:014433TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334434 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4435 HttpRequestInfo request;
4436 request.method = "GET";
4437 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104438 request.traffic_annotation =
4439 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334440
4441 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594442 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494443 ProxyResolutionService::CreateFixedFromPacResult(
4444 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334445
Jeremy Roman0579ed62017-08-29 15:56:194446 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334447 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194448 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334449 mock_handler->set_allows_default_credentials(true);
4450 auth_handler_factory->AddMockHandler(mock_handler.release(),
4451 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484452 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334453
4454 // Add NetLog just so can verify load timing information gets a NetLog ID.
4455 NetLog net_log;
4456 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094457 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334458
4459 // Should try to establish tunnel.
4460 MockWrite data_writes1[] = {
4461 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174462 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334463 "Proxy-Connection: keep-alive\r\n\r\n"),
4464
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"
4468 "Proxy-Authorization: auth_token\r\n\r\n"),
4469 };
4470
4471 // The proxy responds to the connect with a 407, and then hangs up after the
4472 // second request is sent.
4473 MockRead data_reads1[] = {
4474 // No credentials.
4475 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4476 MockRead("Content-Length: 0\r\n"),
4477 MockRead("Proxy-Connection: keep-alive\r\n"),
4478 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4479 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4480 };
4481
4482 // HttpNetworkTransaction sees a reused connection that was closed with
4483 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4484 // request.
4485 MockWrite data_writes2[] = {
4486 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174487 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334488 "Proxy-Connection: keep-alive\r\n\r\n"),
4489 };
4490
4491 // The proxy, having had more than enough of us, just hangs up.
4492 MockRead data_reads2[] = {
4493 // No credentials.
4494 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4495 };
4496
Ryan Sleevib8d7ea02018-05-07 20:01:014497 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334498 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014499 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334500 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4501
bnc87dcefc2017-05-25 12:47:584502 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194503 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334504
4505 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204506 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014507 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334508
4509 const HttpResponseInfo* response = trans->GetResponseInfo();
4510 ASSERT_TRUE(response);
4511 ASSERT_TRUE(response->headers);
4512 EXPECT_TRUE(response->headers->IsKeepAlive());
4513 EXPECT_EQ(407, response->headers->response_code());
4514 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4515 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584516 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334517
4518 LoadTimingInfo load_timing_info;
4519 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4520
4521 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014522 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334523
4524 trans.reset();
4525 session->CloseAllConnections();
4526}
4527
Asanka Herathbc3f8f62018-11-16 23:08:304528// This test exercises an odd edge case where the proxy closes the connection
4529// after the authentication handshake is complete. Presumably this technique is
4530// used in lieu of returning a 403 or 5xx status code when the authentication
4531// succeeds, but the user is not authorized to connect to the destination
4532// server. There's no standard for what a proxy should do to indicate a blocked
4533// site.
4534TEST_F(HttpNetworkTransactionTest,
4535 AuthAllowsDefaultCredentialsTunnelConnectionClosesBeforeBody) {
4536 HttpRequestInfo request;
4537 request.method = "GET";
4538 request.url = GURL("https://www.example.org/");
4539 request.traffic_annotation =
4540 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4541
4542 // Configure against proxy server "myproxy:70".
4543 session_deps_.proxy_resolution_service =
4544 ProxyResolutionService::CreateFixedFromPacResult(
4545 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4546
Steven Valdez0ef94d02018-11-19 23:28:134547 // When TLS 1.3 is enabled, spurious connections are made as part of the SSL
4548 // version interference probes.
4549 // TODO(crbug.com/906668): Correctly handle version interference probes to
4550 // test TLS 1.3.
4551 SSLConfig config;
4552 config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
4553 session_deps_.ssl_config_service =
4554 std::make_unique<TestSSLConfigService>(config);
4555
Asanka Herathbc3f8f62018-11-16 23:08:304556 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
4557 auth_handler_factory->set_do_init_from_challenge(true);
4558
4559 // Create two mock AuthHandlers. This is because the transaction gets retried
4560 // after the first ERR_CONNECTION_CLOSED since it's ambiguous whether there
4561 // was a real network error.
4562 //
4563 // The handlers support both default and explicit credentials. The retry
4564 // mentioned above should be able to reuse the default identity. Thus there
4565 // should never be a need to prompt for explicit credentials.
4566 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
4567 mock_handler->set_allows_default_credentials(true);
4568 mock_handler->set_allows_explicit_credentials(true);
4569 mock_handler->set_connection_based(true);
4570 auth_handler_factory->AddMockHandler(mock_handler.release(),
4571 HttpAuth::AUTH_PROXY);
4572 mock_handler = std::make_unique<HttpAuthHandlerMock>();
4573 mock_handler->set_allows_default_credentials(true);
4574 mock_handler->set_allows_explicit_credentials(true);
4575 mock_handler->set_connection_based(true);
4576 auth_handler_factory->AddMockHandler(mock_handler.release(),
4577 HttpAuth::AUTH_PROXY);
4578 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4579
4580 NetLog net_log;
4581 session_deps_.net_log = &net_log;
4582 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4583
4584 // Data for both sockets.
4585 //
4586 // Writes are for the tunnel establishment attempts and the
4587 // authentication handshake.
4588 MockWrite data_writes1[] = {
4589 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4590 "Host: www.example.org:443\r\n"
4591 "Proxy-Connection: keep-alive\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 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4599 "Host: www.example.org:443\r\n"
4600 "Proxy-Connection: keep-alive\r\n"
4601 "Proxy-Authorization: auth_token\r\n\r\n"),
4602 };
4603
4604 // The server side of the authentication handshake. Note that the response to
4605 // the final CONNECT request is ERR_CONNECTION_CLOSED.
4606 MockRead data_reads1[] = {
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\r\n\r\n"),
4611
4612 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4613 MockRead("Content-Length: 0\r\n"),
4614 MockRead("Proxy-Connection: keep-alive\r\n"),
4615 MockRead("Proxy-Authenticate: Mock foo\r\n\r\n"),
4616
4617 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4618 };
4619
4620 StaticSocketDataProvider data1(data_reads1, data_writes1);
4621 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4622
4623 // The second socket is for the reconnection attempt. Data is identical to the
4624 // first attempt.
4625 StaticSocketDataProvider data2(data_reads1, data_writes1);
4626 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4627
4628 auto trans =
4629 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4630
4631 TestCompletionCallback callback;
4632 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4633
4634 // Two rounds per handshake. After one retry, the error is propagated up the
4635 // stack.
4636 for (int i = 0; i < 4; ++i) {
4637 EXPECT_THAT(callback.GetResult(rv), IsOk());
4638
4639 const HttpResponseInfo* response = trans->GetResponseInfo();
4640 ASSERT_TRUE(response);
4641 ASSERT_TRUE(response->headers);
4642 EXPECT_EQ(407, response->headers->response_code());
4643 ASSERT_TRUE(trans->IsReadyToRestartForAuth());
4644
4645 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4646 }
4647
4648 // One shall be the number thou shalt retry, and the number of the retrying
4649 // shall be one. Two shalt thou not retry, neither retry thou zero, excepting
4650 // that thou then proceed to one. Three is right out. Once the number one,
4651 // being the first number, be reached, then lobbest thou thy
4652 // ERR_CONNECTION_CLOSED towards they network transaction, who shall snuff it.
4653 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.GetResult(rv));
4654
4655 trans.reset();
4656 session->CloseAllConnections();
4657}
4658
mmenke2a1781d2015-10-07 19:25:334659// Test a proxy auth scheme that allows default credentials and a proxy server
4660// that hangs up when credentials are initially sent, and sends a challenge
4661// again they are retried.
bncd16676a2016-07-20 16:23:014662TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334663 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4664 HttpRequestInfo request;
4665 request.method = "GET";
4666 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104667 request.traffic_annotation =
4668 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334669
4670 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594671 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494672 ProxyResolutionService::CreateFixedFromPacResult(
4673 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334674
Jeremy Roman0579ed62017-08-29 15:56:194675 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334676 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194677 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334678 mock_handler->set_allows_default_credentials(true);
4679 auth_handler_factory->AddMockHandler(mock_handler.release(),
4680 HttpAuth::AUTH_PROXY);
4681 // Add another handler for the second challenge. It supports default
4682 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194683 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334684 mock_handler->set_allows_default_credentials(true);
4685 auth_handler_factory->AddMockHandler(mock_handler.release(),
4686 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484687 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334688
4689 // Add NetLog just so can verify load timing information gets a NetLog ID.
4690 NetLog net_log;
4691 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094692 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334693
4694 // Should try to establish tunnel.
4695 MockWrite data_writes1[] = {
4696 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174697 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334698 "Proxy-Connection: keep-alive\r\n\r\n"),
4699 };
4700
4701 // The proxy responds to the connect with a 407, using a non-persistent
4702 // connection.
4703 MockRead data_reads1[] = {
4704 // No credentials.
4705 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4706 MockRead("Proxy-Authenticate: Mock\r\n"),
4707 MockRead("Proxy-Connection: close\r\n\r\n"),
4708 };
4709
4710 // Since the first connection was closed, need to establish another once given
4711 // credentials.
4712 MockWrite data_writes2[] = {
4713 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174714 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334715 "Proxy-Connection: keep-alive\r\n"
4716 "Proxy-Authorization: auth_token\r\n\r\n"),
4717 };
4718
4719 MockRead data_reads2[] = {
4720 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4721 MockRead("Proxy-Authenticate: Mock\r\n"),
4722 MockRead("Proxy-Connection: close\r\n\r\n"),
4723 };
4724
Ryan Sleevib8d7ea02018-05-07 20:01:014725 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334726 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014727 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334728 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4729 SSLSocketDataProvider ssl(ASYNC, OK);
4730 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4731
bnc87dcefc2017-05-25 12:47:584732 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194733 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334734
4735 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204736 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014737 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334738
4739 const HttpResponseInfo* response = trans->GetResponseInfo();
4740 ASSERT_TRUE(response);
4741 ASSERT_TRUE(response->headers);
4742 EXPECT_EQ(407, response->headers->response_code());
4743 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4744 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584745 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334746
4747 LoadTimingInfo load_timing_info;
4748 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4749
4750 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014751 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334752 response = trans->GetResponseInfo();
4753 ASSERT_TRUE(response);
4754 ASSERT_TRUE(response->headers);
4755 EXPECT_EQ(407, response->headers->response_code());
4756 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584757 EXPECT_TRUE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334758
4759 trans.reset();
4760 session->CloseAllConnections();
4761}
4762
asankae2257db2016-10-11 22:03:164763// A more nuanced test than GenerateAuthToken test which asserts that
4764// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4765// unnecessarily invalidated, and that if the server co-operates, the
4766// authentication handshake can continue with the same scheme but with a
4767// different identity.
4768TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4769 HttpRequestInfo request;
4770 request.method = "GET";
4771 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104772 request.traffic_annotation =
4773 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164774
Jeremy Roman0579ed62017-08-29 15:56:194775 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164776 auth_handler_factory->set_do_init_from_challenge(true);
4777
4778 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194779 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164780 mock_handler->set_allows_default_credentials(true);
4781 mock_handler->set_allows_explicit_credentials(true);
4782 mock_handler->set_connection_based(true);
4783 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4784 auth_handler_factory->AddMockHandler(mock_handler.release(),
4785 HttpAuth::AUTH_SERVER);
4786
4787 // Add another handler for the second challenge. It supports default
4788 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194789 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164790 mock_handler->set_allows_default_credentials(true);
4791 mock_handler->set_allows_explicit_credentials(true);
4792 mock_handler->set_connection_based(true);
4793 auth_handler_factory->AddMockHandler(mock_handler.release(),
4794 HttpAuth::AUTH_SERVER);
4795 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4796
4797 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4798
4799 MockWrite data_writes1[] = {
4800 MockWrite("GET / HTTP/1.1\r\n"
4801 "Host: www.example.org\r\n"
4802 "Connection: keep-alive\r\n\r\n"),
4803 };
4804
4805 MockRead data_reads1[] = {
4806 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4807 "WWW-Authenticate: Mock\r\n"
4808 "Connection: keep-alive\r\n\r\n"),
4809 };
4810
4811 // Identical to data_writes1[]. The AuthHandler encounters a
4812 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4813 // transaction procceds without an authorization header.
4814 MockWrite data_writes2[] = {
4815 MockWrite("GET / HTTP/1.1\r\n"
4816 "Host: www.example.org\r\n"
4817 "Connection: keep-alive\r\n\r\n"),
4818 };
4819
4820 MockRead data_reads2[] = {
4821 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4822 "WWW-Authenticate: Mock\r\n"
4823 "Connection: keep-alive\r\n\r\n"),
4824 };
4825
4826 MockWrite data_writes3[] = {
4827 MockWrite("GET / HTTP/1.1\r\n"
4828 "Host: www.example.org\r\n"
4829 "Connection: keep-alive\r\n"
4830 "Authorization: auth_token\r\n\r\n"),
4831 };
4832
4833 MockRead data_reads3[] = {
4834 MockRead("HTTP/1.1 200 OK\r\n"
4835 "Content-Length: 5\r\n"
4836 "Content-Type: text/plain\r\n"
4837 "Connection: keep-alive\r\n\r\n"
4838 "Hello"),
4839 };
4840
Ryan Sleevib8d7ea02018-05-07 20:01:014841 StaticSocketDataProvider data1(data_reads1, data_writes1);
asankae2257db2016-10-11 22:03:164842 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4843
Ryan Sleevib8d7ea02018-05-07 20:01:014844 StaticSocketDataProvider data2(data_reads2, data_writes2);
asankae2257db2016-10-11 22:03:164845 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4846
Ryan Sleevib8d7ea02018-05-07 20:01:014847 StaticSocketDataProvider data3(data_reads3, data_writes3);
asankae2257db2016-10-11 22:03:164848 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4849
bnc87dcefc2017-05-25 12:47:584850 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194851 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164852
4853 TestCompletionCallback callback;
4854 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4855 EXPECT_THAT(callback.GetResult(rv), IsOk());
4856
4857 const HttpResponseInfo* response = trans->GetResponseInfo();
4858 ASSERT_TRUE(response);
4859 ASSERT_TRUE(response->headers);
4860 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4861
4862 // The following three tests assert that an authentication challenge was
4863 // received and that the stack is ready to respond to the challenge using
4864 // ambient credentials.
4865 EXPECT_EQ(401, response->headers->response_code());
4866 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584867 EXPECT_FALSE(response->auth_challenge.has_value());
asankae2257db2016-10-11 22:03:164868
4869 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4870 EXPECT_THAT(callback.GetResult(rv), IsOk());
4871 response = trans->GetResponseInfo();
4872 ASSERT_TRUE(response);
4873 ASSERT_TRUE(response->headers);
4874
4875 // The following three tests assert that an authentication challenge was
4876 // received and that the stack needs explicit credentials before it is ready
4877 // to respond to the challenge.
4878 EXPECT_EQ(401, response->headers->response_code());
4879 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584880 EXPECT_TRUE(response->auth_challenge.has_value());
asankae2257db2016-10-11 22:03:164881
4882 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4883 EXPECT_THAT(callback.GetResult(rv), IsOk());
4884 response = trans->GetResponseInfo();
4885 ASSERT_TRUE(response);
4886 ASSERT_TRUE(response->headers);
4887 EXPECT_EQ(200, response->headers->response_code());
4888
4889 trans.reset();
4890 session->CloseAllConnections();
4891}
4892
Matt Menked1eb6d42018-01-17 04:54:064893// Proxy resolver that returns a proxy with the same host and port for different
4894// schemes, based on the path of the URL being requests.
4895class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4896 public:
4897 SameProxyWithDifferentSchemesProxyResolver() {}
4898 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4899
4900 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4901
4902 static HostPortPair ProxyHostPortPair() {
4903 return HostPortPair::FromString(ProxyHostPortPairAsString());
4904 }
4905
4906 // ProxyResolver implementation.
4907 int GetProxyForURL(const GURL& url,
4908 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:174909 CompletionOnceCallback callback,
Matt Menked1eb6d42018-01-17 04:54:064910 std::unique_ptr<Request>* request,
4911 const NetLogWithSource& /*net_log*/) override {
4912 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574913 results->set_traffic_annotation(
4914 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064915 if (url.path() == "/socks4") {
4916 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4917 return OK;
4918 }
4919 if (url.path() == "/socks5") {
4920 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4921 return OK;
4922 }
4923 if (url.path() == "/http") {
4924 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4925 return OK;
4926 }
4927 if (url.path() == "/https") {
4928 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4929 return OK;
4930 }
Matt Menkee8648fa2019-01-17 16:47:074931 if (url.path() == "/https_trusted") {
4932 results->UseProxyServer(ProxyServer(ProxyServer::SCHEME_HTTPS,
4933 ProxyHostPortPair(),
4934 true /* is_trusted_proxy */));
4935 return OK;
4936 }
Matt Menked1eb6d42018-01-17 04:54:064937 NOTREACHED();
4938 return ERR_NOT_IMPLEMENTED;
4939 }
4940
4941 private:
4942 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4943};
4944
4945class SameProxyWithDifferentSchemesProxyResolverFactory
4946 : public ProxyResolverFactory {
4947 public:
4948 SameProxyWithDifferentSchemesProxyResolverFactory()
4949 : ProxyResolverFactory(false) {}
4950
Lily Houghton99597862018-03-07 16:40:424951 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4952 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:174953 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:424954 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064955 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4956 return OK;
4957 }
4958
4959 private:
4960 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4961};
4962
4963// Check that when different proxy schemes are all applied to a proxy at the
Matt Menkee8648fa2019-01-17 16:47:074964// same address, the connections are not grouped together. i.e., a request to
Matt Menked1eb6d42018-01-17 04:54:064965// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4966// request to foo.com using proxy.com as an HTTP proxy.
4967TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494968 session_deps_.proxy_resolution_service =
4969 std::make_unique<ProxyResolutionService>(
4970 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4971 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4972 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4973 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064974
4975 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4976
4977 MockWrite socks_writes[] = {
4978 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4979 kSOCKS4OkRequestLocalHostPort80Length),
4980 MockWrite(SYNCHRONOUS,
4981 "GET /socks4 HTTP/1.1\r\n"
4982 "Host: test\r\n"
4983 "Connection: keep-alive\r\n\r\n"),
4984 };
4985 MockRead socks_reads[] = {
4986 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4987 MockRead("HTTP/1.0 200 OK\r\n"
4988 "Connection: keep-alive\r\n"
4989 "Content-Length: 15\r\n\r\n"
4990 "SOCKS4 Response"),
4991 };
Ryan Sleevib8d7ea02018-05-07 20:01:014992 StaticSocketDataProvider socks_data(socks_reads, socks_writes);
Matt Menked1eb6d42018-01-17 04:54:064993 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4994
4995 const char kSOCKS5Request[] = {
4996 0x05, // Version
4997 0x01, // Command (CONNECT)
4998 0x00, // Reserved
4999 0x03, // Address type (DOMAINNAME)
5000 0x04, // Length of domain (4)
5001 't', 'e', 's', 't', // Domain string
5002 0x00, 0x50, // 16-bit port (80)
5003 };
5004 MockWrite socks5_writes[] = {
5005 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Avi Drissman4365a4782018-12-28 19:26:245006 MockWrite(ASYNC, kSOCKS5Request, base::size(kSOCKS5Request)),
Matt Menked1eb6d42018-01-17 04:54:065007 MockWrite(SYNCHRONOUS,
5008 "GET /socks5 HTTP/1.1\r\n"
5009 "Host: test\r\n"
5010 "Connection: keep-alive\r\n\r\n"),
5011 };
5012 MockRead socks5_reads[] = {
5013 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
5014 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
5015 MockRead("HTTP/1.0 200 OK\r\n"
5016 "Connection: keep-alive\r\n"
5017 "Content-Length: 15\r\n\r\n"
5018 "SOCKS5 Response"),
5019 };
Ryan Sleevib8d7ea02018-05-07 20:01:015020 StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
Matt Menked1eb6d42018-01-17 04:54:065021 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
5022
5023 MockWrite http_writes[] = {
5024 MockWrite(SYNCHRONOUS,
5025 "GET http://test/http HTTP/1.1\r\n"
5026 "Host: test\r\n"
5027 "Proxy-Connection: keep-alive\r\n\r\n"),
5028 };
5029 MockRead http_reads[] = {
5030 MockRead("HTTP/1.1 200 OK\r\n"
5031 "Proxy-Connection: keep-alive\r\n"
5032 "Content-Length: 13\r\n\r\n"
5033 "HTTP Response"),
5034 };
Ryan Sleevib8d7ea02018-05-07 20:01:015035 StaticSocketDataProvider http_data(http_reads, http_writes);
Matt Menked1eb6d42018-01-17 04:54:065036 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
5037
5038 MockWrite https_writes[] = {
5039 MockWrite(SYNCHRONOUS,
5040 "GET http://test/https HTTP/1.1\r\n"
5041 "Host: test\r\n"
5042 "Proxy-Connection: keep-alive\r\n\r\n"),
5043 };
5044 MockRead https_reads[] = {
5045 MockRead("HTTP/1.1 200 OK\r\n"
5046 "Proxy-Connection: keep-alive\r\n"
5047 "Content-Length: 14\r\n\r\n"
5048 "HTTPS Response"),
5049 };
Ryan Sleevib8d7ea02018-05-07 20:01:015050 StaticSocketDataProvider https_data(https_reads, https_writes);
Matt Menked1eb6d42018-01-17 04:54:065051 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
5052 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
5053 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5054
Matt Menkee8648fa2019-01-17 16:47:075055 MockWrite https_trusted_writes[] = {
5056 MockWrite(SYNCHRONOUS,
5057 "GET http://test/https_trusted HTTP/1.1\r\n"
5058 "Host: test\r\n"
5059 "Proxy-Connection: keep-alive\r\n\r\n"),
5060 };
5061 MockRead https_trusted_reads[] = {
5062 MockRead("HTTP/1.1 200 OK\r\n"
5063 "Proxy-Connection: keep-alive\r\n"
5064 "Content-Length: 22\r\n\r\n"
5065 "HTTPS Trusted Response"),
5066 };
5067 StaticSocketDataProvider trusted_https_data(https_trusted_reads,
5068 https_trusted_writes);
5069 session_deps_.socket_factory->AddSocketDataProvider(&trusted_https_data);
5070 SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
5071 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
5072
Matt Menked1eb6d42018-01-17 04:54:065073 struct TestCase {
5074 GURL url;
5075 std::string expected_response;
Matt Menkee8648fa2019-01-17 16:47:075076 // How many idle sockets there should be in the SOCKS 4/5 proxy socket pools
Matt Menked1eb6d42018-01-17 04:54:065077 // after the test.
Matt Menkee8648fa2019-01-17 16:47:075078 int expected_idle_socks4_sockets;
5079 int expected_idle_socks5_sockets;
5080 // How many idle sockets there should be in the HTTP/HTTPS proxy socket
5081 // pools after the test.
Matt Menked1eb6d42018-01-17 04:54:065082 int expected_idle_http_sockets;
Matt Menkee8648fa2019-01-17 16:47:075083 int expected_idle_https_sockets;
5084 // How many idle sockets there should be in the HTTPS proxy socket pool with
5085 // the ProxyServer's |is_trusted_proxy| bit set after the test.
5086 int expected_idle_trusted_https_sockets;
Matt Menked1eb6d42018-01-17 04:54:065087 } const kTestCases[] = {
Matt Menkee8648fa2019-01-17 16:47:075088 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0, 0, 0, 0},
5089 {GURL("http://test/socks5"), "SOCKS5 Response", 1, 1, 0, 0, 0},
5090 {GURL("http://test/http"), "HTTP Response", 1, 1, 1, 0, 0},
5091 {GURL("http://test/https"), "HTTPS Response", 1, 1, 1, 1, 0},
5092 {GURL("http://test/https_trusted"), "HTTPS Trusted Response", 1, 1, 1, 1,
5093 1},
Matt Menked1eb6d42018-01-17 04:54:065094 };
5095
5096 for (const auto& test_case : kTestCases) {
5097 HttpRequestInfo request;
5098 request.method = "GET";
5099 request.url = test_case.url;
Ramin Halavatib5e433e2018-02-07 07:41:105100 request.traffic_annotation =
5101 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:065102 std::unique_ptr<HttpNetworkTransaction> trans =
5103 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
5104 session.get());
5105 TestCompletionCallback callback;
5106 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5107 EXPECT_THAT(callback.GetResult(rv), IsOk());
5108
5109 const HttpResponseInfo* response = trans->GetResponseInfo();
5110 ASSERT_TRUE(response);
5111 ASSERT_TRUE(response->headers);
5112 EXPECT_EQ(200, response->headers->response_code());
5113 std::string response_data;
5114 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
5115 EXPECT_EQ(test_case.expected_response, response_data);
5116
5117 // Return the socket to the socket pool, so can make sure it's not used for
5118 // the next requests.
5119 trans.reset();
5120 base::RunLoop().RunUntilIdle();
5121
5122 // Check the number of idle sockets in the pool, to make sure that used
5123 // sockets are indeed being returned to the socket pool. If each request
5124 // doesn't return an idle socket to the pool, the test would incorrectly
5125 // pass.
Matt Menkee8648fa2019-01-17 16:47:075126 EXPECT_EQ(test_case.expected_idle_socks4_sockets,
5127 session
Matt Menked23ab952019-03-06 00:24:405128 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075129 HttpNetworkSession::NORMAL_SOCKET_POOL,
5130 ProxyServer(ProxyServer::SCHEME_SOCKS4,
5131 SameProxyWithDifferentSchemesProxyResolver::
5132 ProxyHostPortPair()))
5133 ->IdleSocketCount());
5134 EXPECT_EQ(test_case.expected_idle_socks5_sockets,
5135 session
Matt Menked23ab952019-03-06 00:24:405136 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075137 HttpNetworkSession::NORMAL_SOCKET_POOL,
5138 ProxyServer(ProxyServer::SCHEME_SOCKS5,
5139 SameProxyWithDifferentSchemesProxyResolver::
5140 ProxyHostPortPair()))
5141 ->IdleSocketCount());
5142 EXPECT_EQ(test_case.expected_idle_http_sockets,
5143 session
Matt Menked23ab952019-03-06 00:24:405144 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075145 HttpNetworkSession::NORMAL_SOCKET_POOL,
5146 ProxyServer(ProxyServer::SCHEME_HTTP,
5147 SameProxyWithDifferentSchemesProxyResolver::
5148 ProxyHostPortPair()))
5149 ->IdleSocketCount());
5150 EXPECT_EQ(test_case.expected_idle_https_sockets,
5151 session
Matt Menked23ab952019-03-06 00:24:405152 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075153 HttpNetworkSession::NORMAL_SOCKET_POOL,
5154 ProxyServer(ProxyServer::SCHEME_HTTPS,
5155 SameProxyWithDifferentSchemesProxyResolver::
5156 ProxyHostPortPair()))
5157 ->IdleSocketCount());
5158 EXPECT_EQ(test_case.expected_idle_trusted_https_sockets,
5159 session
Matt Menked23ab952019-03-06 00:24:405160 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075161 HttpNetworkSession::NORMAL_SOCKET_POOL,
5162 ProxyServer(ProxyServer::SCHEME_HTTPS,
5163 SameProxyWithDifferentSchemesProxyResolver::
5164 ProxyHostPortPair(),
5165 true /* is_trusted_proxy */))
5166 ->IdleSocketCount());
Matt Menked1eb6d42018-01-17 04:54:065167 }
5168}
5169
[email protected]029c83b62013-01-24 05:28:205170// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:015171TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205172 HttpRequestInfo request1;
5173 request1.method = "GET";
bncce36dca22015-04-21 22:11:235174 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:105175 request1.traffic_annotation =
5176 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205177
5178 HttpRequestInfo request2;
5179 request2.method = "GET";
bncce36dca22015-04-21 22:11:235180 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:105181 request2.traffic_annotation =
5182 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205183
5184 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495185 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5186 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515187 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075188 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095189 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205190
5191 // Since we have proxy, should try to establish tunnel.
5192 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175193 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5194 "Host: www.example.org:443\r\n"
5195 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205196
rsleevidb16bb02015-11-12 23:47:175197 MockWrite("GET /1 HTTP/1.1\r\n"
5198 "Host: www.example.org\r\n"
5199 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205200
rsleevidb16bb02015-11-12 23:47:175201 MockWrite("GET /2 HTTP/1.1\r\n"
5202 "Host: www.example.org\r\n"
5203 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205204 };
5205
5206 // The proxy responds to the connect with a 407, using a persistent
5207 // connection.
5208 MockRead data_reads1[] = {
5209 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5210
5211 MockRead("HTTP/1.1 200 OK\r\n"),
5212 MockRead("Content-Length: 1\r\n\r\n"),
5213 MockRead(SYNCHRONOUS, "1"),
5214
5215 MockRead("HTTP/1.1 200 OK\r\n"),
5216 MockRead("Content-Length: 2\r\n\r\n"),
5217 MockRead(SYNCHRONOUS, "22"),
5218 };
5219
Ryan Sleevib8d7ea02018-05-07 20:01:015220 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075221 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205222 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075223 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205224
5225 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585226 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195227 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205228
5229 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015230 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205231
5232 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015233 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205234
5235 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525236 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:475237 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:525238 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205239 EXPECT_EQ(1, response1->headers->GetContentLength());
5240
5241 LoadTimingInfo load_timing_info1;
5242 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5243 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
5244
5245 trans1.reset();
5246
5247 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585248 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195249 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205250
5251 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015252 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205253
5254 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015255 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205256
5257 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525258 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:475259 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:525260 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205261 EXPECT_EQ(2, response2->headers->GetContentLength());
5262
5263 LoadTimingInfo load_timing_info2;
5264 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5265 TestLoadTimingReused(load_timing_info2);
5266
5267 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5268
5269 trans2.reset();
5270 session->CloseAllConnections();
5271}
5272
5273// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:015274TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205275 HttpRequestInfo request1;
5276 request1.method = "GET";
bncce36dca22015-04-21 22:11:235277 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:105278 request1.traffic_annotation =
5279 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205280
5281 HttpRequestInfo request2;
5282 request2.method = "GET";
bncce36dca22015-04-21 22:11:235283 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:105284 request2.traffic_annotation =
5285 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205286
5287 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595288 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:495289 ProxyResolutionService::CreateFixedFromPacResult(
5290 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515291 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075292 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095293 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205294
5295 // Since we have proxy, should try to establish tunnel.
5296 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175297 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5298 "Host: www.example.org:443\r\n"
5299 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205300
rsleevidb16bb02015-11-12 23:47:175301 MockWrite("GET /1 HTTP/1.1\r\n"
5302 "Host: www.example.org\r\n"
5303 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205304
rsleevidb16bb02015-11-12 23:47:175305 MockWrite("GET /2 HTTP/1.1\r\n"
5306 "Host: www.example.org\r\n"
5307 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205308 };
5309
5310 // The proxy responds to the connect with a 407, using a persistent
5311 // connection.
5312 MockRead data_reads1[] = {
5313 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5314
5315 MockRead("HTTP/1.1 200 OK\r\n"),
5316 MockRead("Content-Length: 1\r\n\r\n"),
5317 MockRead(SYNCHRONOUS, "1"),
5318
5319 MockRead("HTTP/1.1 200 OK\r\n"),
5320 MockRead("Content-Length: 2\r\n\r\n"),
5321 MockRead(SYNCHRONOUS, "22"),
5322 };
5323
Ryan Sleevib8d7ea02018-05-07 20:01:015324 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075325 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205326 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075327 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205328
5329 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585330 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195331 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205332
5333 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015334 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205335
5336 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015337 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205338
5339 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525340 ASSERT_TRUE(response1);
5341 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205342 EXPECT_EQ(1, response1->headers->GetContentLength());
5343
5344 LoadTimingInfo load_timing_info1;
5345 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5346 TestLoadTimingNotReusedWithPac(load_timing_info1,
5347 CONNECT_TIMING_HAS_SSL_TIMES);
5348
5349 trans1.reset();
5350
5351 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585352 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195353 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205354
5355 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015356 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205357
5358 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015359 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205360
5361 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525362 ASSERT_TRUE(response2);
5363 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205364 EXPECT_EQ(2, response2->headers->GetContentLength());
5365
5366 LoadTimingInfo load_timing_info2;
5367 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5368 TestLoadTimingReusedWithPac(load_timing_info2);
5369
5370 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5371
5372 trans2.reset();
5373 session->CloseAllConnections();
5374}
5375
[email protected]2df19bb2010-08-25 20:13:465376// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015377TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275378 HttpRequestInfo request;
5379 request.method = "GET";
bncce36dca22015-04-21 22:11:235380 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105381 request.traffic_annotation =
5382 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275383
[email protected]2df19bb2010-08-25 20:13:465384 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495385 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5386 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515387 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075388 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095389 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465390
[email protected]2df19bb2010-08-25 20:13:465391 // Since we have proxy, should use full url
5392 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235393 MockWrite(
5394 "GET http://www.example.org/ HTTP/1.1\r\n"
5395 "Host: www.example.org\r\n"
5396 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465397 };
5398
5399 MockRead data_reads1[] = {
5400 MockRead("HTTP/1.1 200 OK\r\n"),
5401 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5402 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065403 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465404 };
5405
Ryan Sleevib8d7ea02018-05-07 20:01:015406 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075407 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065408 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075409 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465410
[email protected]49639fa2011-12-20 23:22:415411 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465412
bnc691fda62016-08-12 00:43:165413 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505414
bnc691fda62016-08-12 00:43:165415 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015416 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465417
5418 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015419 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465420
[email protected]58e32bb2013-01-21 18:23:255421 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165422 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255423 TestLoadTimingNotReused(load_timing_info,
5424 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5425
bnc691fda62016-08-12 00:43:165426 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525427 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465428
tbansal2ecbbc72016-10-06 17:15:475429 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465430 EXPECT_TRUE(response->headers->IsKeepAlive());
5431 EXPECT_EQ(200, response->headers->response_code());
5432 EXPECT_EQ(100, response->headers->GetContentLength());
5433 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5434
5435 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:585436 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]2df19bb2010-08-25 20:13:465437}
5438
[email protected]7642b5ae2010-09-01 20:55:175439// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015440TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275441 HttpRequestInfo request;
5442 request.method = "GET";
bncce36dca22015-04-21 22:11:235443 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105444 request.traffic_annotation =
5445 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275446
[email protected]7642b5ae2010-09-01 20:55:175447 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495448 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5449 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515450 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075451 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095452 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175453
bncce36dca22015-04-21 22:11:235454 // fetch http://www.example.org/ via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135455 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455456 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415457 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175458
Ryan Hamilton0239aac2018-05-19 00:03:135459 spdy::SpdySerializedFrame resp(
5460 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5461 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175462 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415463 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175464 };
5465
Ryan Sleevib8d7ea02018-05-07 20:01:015466 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075467 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175468
[email protected]8ddf8322012-02-23 18:08:065469 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365470 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075471 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175472
[email protected]49639fa2011-12-20 23:22:415473 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175474
bnc691fda62016-08-12 00:43:165475 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505476
bnc691fda62016-08-12 00:43:165477 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015478 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175479
5480 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015481 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175482
[email protected]58e32bb2013-01-21 18:23:255483 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165484 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255485 TestLoadTimingNotReused(load_timing_info,
5486 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5487
bnc691fda62016-08-12 00:43:165488 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525489 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475490 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525491 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025492 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175493
5494 std::string response_data;
bnc691fda62016-08-12 00:43:165495 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235496 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175497}
5498
[email protected]1c173852014-06-19 12:51:505499// Verifies that a session which races and wins against the owning transaction
5500// (completing prior to host resolution), doesn't fail the transaction.
5501// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015502TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505503 HttpRequestInfo request;
5504 request.method = "GET";
bncce36dca22015-04-21 22:11:235505 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105506 request.traffic_annotation =
5507 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505508
5509 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495510 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5511 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515512 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505513 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095514 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505515
bncce36dca22015-04-21 22:11:235516 // Fetch http://www.example.org/ through the SPDY proxy.
Ryan Hamilton0239aac2018-05-19 00:03:135517 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455518 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415519 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505520
Raul Tambre94493c652019-03-11 17:18:355521 spdy::SpdySerializedFrame resp(
5522 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135523 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505524 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415525 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505526 };
5527
Ryan Sleevib8d7ea02018-05-07 20:01:015528 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]1c173852014-06-19 12:51:505529 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5530
5531 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365532 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505533 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5534
5535 TestCompletionCallback callback1;
5536
bnc691fda62016-08-12 00:43:165537 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505538
5539 // Stall the hostname resolution begun by the transaction.
[email protected]1c173852014-06-19 12:51:505540 session_deps_.host_resolver->set_ondemand_mode(true);
5541
bnc691fda62016-08-12 00:43:165542 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015543 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505544
5545 // Race a session to the proxy, which completes first.
5546 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045547 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:115548 PRIVACY_MODE_DISABLED,
5549 SpdySessionKey::IsProxySession::kTrue, SocketTag());
[email protected]1c173852014-06-19 12:51:505550 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525551 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505552
5553 // Unstall the resolution begun by the transaction.
5554 session_deps_.host_resolver->set_ondemand_mode(true);
5555 session_deps_.host_resolver->ResolveAllPending();
5556
5557 EXPECT_FALSE(callback1.have_result());
5558 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015559 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505560
bnc691fda62016-08-12 00:43:165561 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525562 ASSERT_TRUE(response);
5563 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025564 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505565
5566 std::string response_data;
bnc691fda62016-08-12 00:43:165567 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505568 EXPECT_EQ(kUploadData, response_data);
5569}
5570
[email protected]dc7bd1c52010-11-12 00:01:135571// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015572TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275573 HttpRequestInfo request;
5574 request.method = "GET";
bncce36dca22015-04-21 22:11:235575 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105576 request.traffic_annotation =
5577 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275578
[email protected]79cb5c12011-09-12 13:12:045579 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495580 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5581 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515582 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075583 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095584 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135585
[email protected]dc7bd1c52010-11-12 00:01:135586 // The first request will be a bare GET, the second request will be a
5587 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455588 spdy_util_.set_default_url(request.url);
Ryan Hamilton0239aac2018-05-19 00:03:135589 spdy::SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485590 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385591 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135592 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465593 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135594 };
Ryan Hamilton0239aac2018-05-19 00:03:135595 spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
Avi Drissman4365a4782018-12-28 19:26:245596 kExtraAuthorizationHeaders, base::size(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485597 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135598 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415599 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135600 };
5601
5602 // The first response is a 407 proxy authentication challenge, and the second
5603 // response will be a 200 response since the second request includes a valid
5604 // Authorization header.
5605 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465606 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135607 };
Ryan Hamilton0239aac2018-05-19 00:03:135608 spdy::SpdySerializedFrame resp_authentication(
5609 spdy_util_.ConstructSpdyReplyError(
5610 "407", kExtraAuthenticationHeaders,
Avi Drissman4365a4782018-12-28 19:26:245611 base::size(kExtraAuthenticationHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135612 spdy::SpdySerializedFrame body_authentication(
bncdf80d44fd2016-07-15 20:27:415613 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:135614 spdy::SpdySerializedFrame resp_data(
Raul Tambre94493c652019-03-11 17:18:355615 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:135616 spdy::SpdySerializedFrame body_data(
5617 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135618 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415619 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465620 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415621 CreateMockRead(resp_data, 4),
5622 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135623 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135624 };
5625
Ryan Sleevib8d7ea02018-05-07 20:01:015626 SequencedSocketData data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075627 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135628
[email protected]8ddf8322012-02-23 18:08:065629 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365630 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075631 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135632
[email protected]49639fa2011-12-20 23:22:415633 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135634
bnc691fda62016-08-12 00:43:165635 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135636
bnc691fda62016-08-12 00:43:165637 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015638 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135639
5640 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015641 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135642
bnc691fda62016-08-12 00:43:165643 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135644
wezca1070932016-05-26 20:30:525645 ASSERT_TRUE(response);
5646 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135647 EXPECT_EQ(407, response->headers->response_code());
5648 EXPECT_TRUE(response->was_fetched_via_spdy);
Emily Starkf2c9bbd2019-04-09 17:08:585649 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
[email protected]dc7bd1c52010-11-12 00:01:135650
[email protected]49639fa2011-12-20 23:22:415651 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135652
bnc691fda62016-08-12 00:43:165653 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015654 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135655
5656 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015657 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135658
bnc691fda62016-08-12 00:43:165659 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135660
wezca1070932016-05-26 20:30:525661 ASSERT_TRUE(response_restart);
5662 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135663 EXPECT_EQ(200, response_restart->headers->response_code());
5664 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:585665 EXPECT_FALSE(response_restart->auth_challenge.has_value());
[email protected]dc7bd1c52010-11-12 00:01:135666}
5667
[email protected]d9da5fe2010-10-13 22:37:165668// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015669TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275670 HttpRequestInfo request;
5671 request.method = "GET";
bncce36dca22015-04-21 22:11:235672 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105673 request.traffic_annotation =
5674 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275675
[email protected]d9da5fe2010-10-13 22:37:165676 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495677 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5678 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515679 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075680 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095681 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165682
bnc691fda62016-08-12 00:43:165683 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165684
bncce36dca22015-04-21 22:11:235685 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135686 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045687 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5688 HostPortPair("www.example.org", 443)));
bncce36dca22015-04-21 22:11:235689 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165690
bncce36dca22015-04-21 22:11:235691 const char get[] =
5692 "GET / HTTP/1.1\r\n"
5693 "Host: www.example.org\r\n"
5694 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135695 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195696 spdy_util_.ConstructSpdyDataFrame(1, get, false));
Ryan Hamilton0239aac2018-05-19 00:03:135697 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:355698 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165699 const char resp[] = "HTTP/1.1 200 OK\r\n"
5700 "Content-Length: 10\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135701 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195702 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:135703 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195704 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
Ryan Hamilton0239aac2018-05-19 00:03:135705 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415706 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045707
5708 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415709 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5710 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045711 };
5712
[email protected]d9da5fe2010-10-13 22:37:165713 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415714 CreateMockRead(conn_resp, 1, ASYNC),
5715 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5716 CreateMockRead(wrapped_body, 4, ASYNC),
5717 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135718 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165719 };
5720
Ryan Sleevib8d7ea02018-05-07 20:01:015721 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075722 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165723
[email protected]8ddf8322012-02-23 18:08:065724 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365725 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075726 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065727 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075728 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165729
[email protected]49639fa2011-12-20 23:22:415730 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165731
bnc691fda62016-08-12 00:43:165732 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165734
5735 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015736 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165737
[email protected]58e32bb2013-01-21 18:23:255738 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165739 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255740 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5741
bnc691fda62016-08-12 00:43:165742 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525743 ASSERT_TRUE(response);
5744 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165745 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5746
5747 std::string response_data;
bnc691fda62016-08-12 00:43:165748 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165749 EXPECT_EQ("1234567890", response_data);
5750}
5751
5752// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015753TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5754 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385755
[email protected]cb9bf6ca2011-01-28 13:15:275756 HttpRequestInfo request;
5757 request.method = "GET";
bncce36dca22015-04-21 22:11:235758 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105759 request.traffic_annotation =
5760 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275761
[email protected]d9da5fe2010-10-13 22:37:165762 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495763 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5764 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515765 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075766 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095767 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165768
bnc691fda62016-08-12 00:43:165769 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165770
bncce36dca22015-04-21 22:11:235771 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135772 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045773 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5774 HostPortPair("www.example.org", 443)));
bncce36dca22015-04-21 22:11:235775 // fetch https://www.example.org/ via SPDY
5776 const char kMyUrl[] = "https://www.example.org/";
Ryan Hamilton0239aac2018-05-19 00:03:135777 spdy::SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495778 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:135779 spdy::SpdySerializedFrame wrapped_get(
5780 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
5781 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:355782 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135783 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:355784 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135785 spdy::SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025786 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135787 spdy::SpdySerializedFrame body(
5788 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5789 spdy::SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025790 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135791 spdy::SpdySerializedFrame window_update_get_resp(
bncdf80d44fd2016-07-15 20:27:415792 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
Ryan Hamilton0239aac2018-05-19 00:03:135793 spdy::SpdySerializedFrame window_update_body(
bncdf80d44fd2016-07-15 20:27:415794 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045795
5796 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415797 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5798 CreateMockWrite(window_update_get_resp, 6),
5799 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045800 };
5801
[email protected]d9da5fe2010-10-13 22:37:165802 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415803 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095804 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415805 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5806 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135807 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165808 };
5809
Ryan Sleevib8d7ea02018-05-07 20:01:015810 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075811 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165812
[email protected]8ddf8322012-02-23 18:08:065813 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365814 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075815 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065816 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365817 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075818 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165819
[email protected]49639fa2011-12-20 23:22:415820 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165821
bnc691fda62016-08-12 00:43:165822 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015823 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165824
rch32320842015-05-16 15:57:095825 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555826 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095827 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595828 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165829 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015830 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165831
[email protected]58e32bb2013-01-21 18:23:255832 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165833 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255834 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5835
bnc691fda62016-08-12 00:43:165836 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525837 ASSERT_TRUE(response);
5838 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025839 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165840
5841 std::string response_data;
bnc691fda62016-08-12 00:43:165842 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235843 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165844}
5845
5846// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015847TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275848 HttpRequestInfo request;
5849 request.method = "GET";
bncce36dca22015-04-21 22:11:235850 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105851 request.traffic_annotation =
5852 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275853
[email protected]d9da5fe2010-10-13 22:37:165854 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495855 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5856 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515857 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075858 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095859 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165860
bnc691fda62016-08-12 00:43:165861 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165862
bncce36dca22015-04-21 22:11:235863 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135864 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045865 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5866 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135867 spdy::SpdySerializedFrame get(
5868 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165869
5870 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415871 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165872 };
5873
Ryan Hamilton0239aac2018-05-19 00:03:135874 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
5875 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165876 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415877 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165878 };
5879
Ryan Sleevib8d7ea02018-05-07 20:01:015880 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075881 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165882
[email protected]8ddf8322012-02-23 18:08:065883 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365884 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075885 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065886 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365887 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075888 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165889
[email protected]49639fa2011-12-20 23:22:415890 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165891
bnc691fda62016-08-12 00:43:165892 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165894
5895 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015896 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165897
ttuttle960fcbf2016-04-19 13:26:325898 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165899}
5900
Matt Menkecb2cd0982018-12-19 17:54:045901// Test the case where a proxied H2 session doesn't exist when an auth challenge
5902// is observed, but does exist by the time auth credentials are provided.
5903// Proxy-Connection: Close is used so that there's a second DNS lookup, which is
5904// what causes the existing H2 session to be noticed and reused.
5905TEST_F(HttpNetworkTransactionTest, ProxiedH2SessionAppearsDuringAuth) {
5906 ProxyConfig proxy_config;
5907 proxy_config.set_auto_detect(true);
5908 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
5909
5910 CapturingProxyResolver capturing_proxy_resolver;
5911 capturing_proxy_resolver.set_proxy_server(
5912 ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 70)));
5913 session_deps_.proxy_resolution_service =
5914 std::make_unique<ProxyResolutionService>(
5915 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
5916 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
5917 std::make_unique<CapturingProxyResolverFactory>(
5918 &capturing_proxy_resolver),
5919 nullptr);
5920
5921 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5922
5923 const char kMyUrl[] = "https://www.example.org/";
5924 spdy::SpdySerializedFrame get(spdy_util_.ConstructSpdyGet(kMyUrl, 1, LOWEST));
5925 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:355926 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menkecb2cd0982018-12-19 17:54:045927 spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
5928
5929 spdy_util_.UpdateWithStreamDestruction(1);
5930 spdy::SpdySerializedFrame get2(
5931 spdy_util_.ConstructSpdyGet(kMyUrl, 3, LOWEST));
5932 spdy::SpdySerializedFrame get_resp2(
Raul Tambre94493c652019-03-11 17:18:355933 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Matt Menkecb2cd0982018-12-19 17:54:045934 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
5935
5936 MockWrite auth_challenge_writes[] = {
5937 MockWrite(ASYNC, 0,
5938 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5939 "Host: www.example.org:443\r\n"
5940 "Proxy-Connection: keep-alive\r\n\r\n"),
5941 };
5942
5943 MockRead auth_challenge_reads[] = {
5944 MockRead(ASYNC, 1,
5945 "HTTP/1.1 407 Authentication Required\r\n"
5946 "Content-Length: 0\r\n"
5947 "Proxy-Connection: close\r\n"
5948 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
5949 };
5950
5951 MockWrite spdy_writes[] = {
5952 MockWrite(ASYNC, 0,
5953 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5954 "Host: www.example.org:443\r\n"
5955 "Proxy-Connection: keep-alive\r\n"
5956 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5957 CreateMockWrite(get, 2),
5958 CreateMockWrite(get2, 5),
5959 };
5960
5961 MockRead spdy_reads[] = {
5962 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
5963 CreateMockRead(get_resp, 3, ASYNC),
5964 CreateMockRead(body, 4, ASYNC),
5965 CreateMockRead(get_resp2, 6, ASYNC),
5966 CreateMockRead(body2, 7, ASYNC),
5967
5968 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 8),
5969 };
5970
5971 SequencedSocketData auth_challenge1(auth_challenge_reads,
5972 auth_challenge_writes);
5973 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge1);
5974
5975 SequencedSocketData auth_challenge2(auth_challenge_reads,
5976 auth_challenge_writes);
5977 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge2);
5978
5979 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
5980 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5981
5982 SSLSocketDataProvider ssl(ASYNC, OK);
5983 ssl.next_proto = kProtoHTTP2;
5984 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5985
5986 TestCompletionCallback callback;
5987 std::string response_data;
5988
5989 // Run first request until an auth challenge is observed.
5990 HttpRequestInfo request1;
5991 request1.method = "GET";
5992 request1.url = GURL(kMyUrl);
5993 request1.traffic_annotation =
5994 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5995 HttpNetworkTransaction trans1(LOWEST, session.get());
5996 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
5997 EXPECT_THAT(callback.GetResult(rv), IsOk());
5998 const HttpResponseInfo* response = trans1.GetResponseInfo();
5999 ASSERT_TRUE(response);
6000 ASSERT_TRUE(response->headers);
6001 EXPECT_EQ(407, response->headers->response_code());
6002 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:586003 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
Matt Menkecb2cd0982018-12-19 17:54:046004
6005 // Run second request until an auth challenge is observed.
6006 HttpRequestInfo request2;
6007 request2.method = "GET";
6008 request2.url = GURL(kMyUrl);
6009 request2.traffic_annotation =
6010 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6011 HttpNetworkTransaction trans2(LOWEST, session.get());
6012 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6013 EXPECT_THAT(callback.GetResult(rv), IsOk());
6014 response = trans2.GetResponseInfo();
6015 ASSERT_TRUE(response);
6016 ASSERT_TRUE(response->headers);
6017 EXPECT_EQ(407, response->headers->response_code());
6018 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:586019 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
Matt Menkecb2cd0982018-12-19 17:54:046020
6021 // Now provide credentials for the first request, and wait for it to complete.
6022 rv = trans1.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6023 rv = callback.GetResult(rv);
6024 EXPECT_THAT(rv, IsOk());
6025 response = trans1.GetResponseInfo();
6026 ASSERT_TRUE(response);
6027 ASSERT_TRUE(response->headers);
6028 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6029 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6030 EXPECT_EQ(kUploadData, response_data);
6031
6032 // Now provide credentials for the second request. It should notice the
6033 // existing session, and reuse it.
6034 rv = trans2.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6035 EXPECT_THAT(callback.GetResult(rv), IsOk());
6036 response = trans2.GetResponseInfo();
6037 ASSERT_TRUE(response);
6038 ASSERT_TRUE(response->headers);
6039 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6040 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6041 EXPECT_EQ(kUploadData, response_data);
6042}
6043
[email protected]f6c63db52013-02-02 00:35:226044// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6045// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:016046TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226047 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
6048 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496049 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6050 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516051 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076052 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096053 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506054 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226055
6056 HttpRequestInfo request1;
6057 request1.method = "GET";
bncce36dca22015-04-21 22:11:236058 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226059 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106060 request1.traffic_annotation =
6061 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226062
6063 HttpRequestInfo request2;
6064 request2.method = "GET";
bncce36dca22015-04-21 22:11:236065 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226066 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106067 request2.traffic_annotation =
6068 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226069
bncce36dca22015-04-21 22:11:236070 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136071 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046072 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6073 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136074 spdy::SpdySerializedFrame conn_resp1(
Raul Tambre94493c652019-03-11 17:18:356075 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226076
bncce36dca22015-04-21 22:11:236077 // Fetch https://www.example.org/ via HTTP.
6078 const char get1[] =
6079 "GET / HTTP/1.1\r\n"
6080 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226081 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136082 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196083 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226084 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6085 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136086 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196087 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136088 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196089 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136090 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416091 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226092
bncce36dca22015-04-21 22:11:236093 // CONNECT to mail.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136094 spdy::SpdyHeaderBlock connect2_block;
6095 connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
6096 connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
6097 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
Matt Menke6e879bd2019-03-18 17:26:046098 3, std::move(connect2_block), HttpProxyConnectJob::kH2QuicTunnelPriority,
6099 false));
[email protected]601e03f12014-04-06 16:26:396100
Ryan Hamilton0239aac2018-05-19 00:03:136101 spdy::SpdySerializedFrame conn_resp2(
Raul Tambre94493c652019-03-11 17:18:356102 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
[email protected]f6c63db52013-02-02 00:35:226103
bncce36dca22015-04-21 22:11:236104 // Fetch https://mail.example.org/ via HTTP.
6105 const char get2[] =
6106 "GET / HTTP/1.1\r\n"
6107 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226108 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136109 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196110 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:226111 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6112 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136113 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196114 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136115 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196116 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:226117
6118 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416119 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6120 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:226121 };
6122
6123 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416124 CreateMockRead(conn_resp1, 1, ASYNC),
6125 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
6126 CreateMockRead(wrapped_body1, 4, ASYNC),
6127 CreateMockRead(conn_resp2, 6, ASYNC),
6128 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
6129 CreateMockRead(wrapped_body2, 9, ASYNC),
6130 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:226131 };
6132
Ryan Sleevib8d7ea02018-05-07 20:01:016133 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506134 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226135
6136 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366137 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506138 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226139 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506140 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226141 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506142 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:226143
6144 TestCompletionCallback callback;
6145
bnc691fda62016-08-12 00:43:166146 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206147 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016148 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226149
6150 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166151 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:226152 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6153
bnc691fda62016-08-12 00:43:166154 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526155 ASSERT_TRUE(response);
6156 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226157 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6158
6159 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446160 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
bnc691fda62016-08-12 00:43:166161 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506162 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226163
bnc691fda62016-08-12 00:43:166164 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206165 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016166 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226167
6168 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166169 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226170 // Even though the SPDY connection is reused, a new tunnelled connection has
6171 // to be created, so the socket's load timing looks like a fresh connection.
6172 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
6173
6174 // The requests should have different IDs, since they each are using their own
6175 // separate stream.
6176 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6177
bnc691fda62016-08-12 00:43:166178 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506179 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226180}
6181
6182// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6183// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:016184TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226185 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
6186 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496187 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6188 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516189 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076190 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096191 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506192 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226193
6194 HttpRequestInfo request1;
6195 request1.method = "GET";
bncce36dca22015-04-21 22:11:236196 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226197 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106198 request1.traffic_annotation =
6199 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226200
6201 HttpRequestInfo request2;
6202 request2.method = "GET";
bncce36dca22015-04-21 22:11:236203 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:226204 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106205 request2.traffic_annotation =
6206 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226207
bncce36dca22015-04-21 22:11:236208 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136209 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046210 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6211 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136212 spdy::SpdySerializedFrame conn_resp1(
Raul Tambre94493c652019-03-11 17:18:356213 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226214
bncce36dca22015-04-21 22:11:236215 // Fetch https://www.example.org/ via HTTP.
6216 const char get1[] =
6217 "GET / HTTP/1.1\r\n"
6218 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226219 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136220 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196221 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226222 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6223 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136224 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196225 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136226 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196227 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136228 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416229 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226230
bncce36dca22015-04-21 22:11:236231 // Fetch https://www.example.org/2 via HTTP.
6232 const char get2[] =
6233 "GET /2 HTTP/1.1\r\n"
6234 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226235 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136236 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196237 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:226238 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6239 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136240 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196241 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136242 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196243 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:226244
6245 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416246 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6247 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:226248 };
6249
6250 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416251 CreateMockRead(conn_resp1, 1, ASYNC),
6252 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:466253 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416254 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:466255 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416256 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:226257 };
6258
Ryan Sleevib8d7ea02018-05-07 20:01:016259 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506260 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226261
6262 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366263 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506264 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226265 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506266 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226267
6268 TestCompletionCallback callback;
6269
bnc87dcefc2017-05-25 12:47:586270 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196271 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206272 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016273 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226274
6275 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016276 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226277
6278 LoadTimingInfo load_timing_info;
6279 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6280 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6281
6282 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526283 ASSERT_TRUE(response);
6284 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226285 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6286
6287 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446288 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
[email protected]90499482013-06-01 00:39:506289 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226290 trans.reset();
6291
bnc87dcefc2017-05-25 12:47:586292 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:196293 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206294 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016295 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226296
[email protected]f6c63db52013-02-02 00:35:226297 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016298 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226299
6300 LoadTimingInfo load_timing_info2;
6301 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
6302 TestLoadTimingReused(load_timing_info2);
6303
6304 // The requests should have the same ID.
6305 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6306
[email protected]90499482013-06-01 00:39:506307 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226308}
6309
6310// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
6311// Proxy to different servers.
bncd16676a2016-07-20 16:23:016312TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:226313 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496314 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6315 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516316 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076317 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096318 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506319 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226320
6321 HttpRequestInfo request1;
6322 request1.method = "GET";
bncce36dca22015-04-21 22:11:236323 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226324 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106325 request1.traffic_annotation =
6326 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226327
6328 HttpRequestInfo request2;
6329 request2.method = "GET";
bncce36dca22015-04-21 22:11:236330 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226331 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106332 request2.traffic_annotation =
6333 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226334
bncce36dca22015-04-21 22:11:236335 // http://www.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136336 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:236337 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136338 spdy::SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:156339 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136340 spdy::SpdySerializedFrame get_resp1(
Raul Tambre94493c652019-03-11 17:18:356341 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:136342 spdy::SpdySerializedFrame body1(
6343 spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:386344 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:226345
bncce36dca22015-04-21 22:11:236346 // http://mail.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136347 spdy::SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:236348 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136349 spdy::SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:156350 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136351 spdy::SpdySerializedFrame get_resp2(
Raul Tambre94493c652019-03-11 17:18:356352 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:136353 spdy::SpdySerializedFrame body2(
6354 spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:226355
6356 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416357 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:226358 };
6359
6360 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416361 CreateMockRead(get_resp1, 1, ASYNC),
6362 CreateMockRead(body1, 2, ASYNC),
6363 CreateMockRead(get_resp2, 4, ASYNC),
6364 CreateMockRead(body2, 5, ASYNC),
6365 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:226366 };
6367
Ryan Sleevib8d7ea02018-05-07 20:01:016368 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506369 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226370
6371 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366372 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506373 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226374
6375 TestCompletionCallback callback;
6376
bnc87dcefc2017-05-25 12:47:586377 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196378 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206379 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016380 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226381
6382 LoadTimingInfo load_timing_info;
6383 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6384 TestLoadTimingNotReused(load_timing_info,
6385 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6386
6387 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526388 ASSERT_TRUE(response);
6389 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:026390 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:226391
6392 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446393 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
mmenke11eb5152015-06-09 14:50:506394 rv = trans->Read(buf.get(), 256, callback.callback());
6395 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226396 // Delete the first request, so the second one can reuse the socket.
6397 trans.reset();
6398
bnc691fda62016-08-12 00:43:166399 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206400 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016401 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226402
6403 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166404 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226405 TestLoadTimingReused(load_timing_info2);
6406
6407 // The requests should have the same ID.
6408 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6409
bnc691fda62016-08-12 00:43:166410 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506411 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226412}
6413
Matt Menke2436b2f2018-12-11 18:07:116414// Test that an HTTP/2 CONNECT through an HTTPS Proxy to a HTTP/2 server and a
6415// direct (non-proxied) request to the proxy server are not pooled, as that
6416// would break socket pool isolation.
6417TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation1) {
6418 ProxyConfig proxy_config;
6419 proxy_config.set_auto_detect(true);
6420 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6421
6422 CapturingProxyResolver capturing_proxy_resolver;
6423 session_deps_.proxy_resolution_service =
6424 std::make_unique<ProxyResolutionService>(
6425 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6426 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6427 std::make_unique<CapturingProxyResolverFactory>(
6428 &capturing_proxy_resolver),
6429 nullptr);
6430
6431 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6432
6433 SpdyTestUtil spdy_util1;
6434 // CONNECT to www.example.org:443 via HTTP/2.
6435 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046436 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6437 HostPortPair("www.example.org", 443)));
Matt Menke2436b2f2018-12-11 18:07:116438 // fetch https://www.example.org/ via HTTP/2.
6439 const char kMyUrl[] = "https://www.example.org/";
6440 spdy::SpdySerializedFrame get(spdy_util1.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6441 spdy::SpdySerializedFrame wrapped_get(
6442 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6443 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:356444 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menke2436b2f2018-12-11 18:07:116445 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:356446 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menke2436b2f2018-12-11 18:07:116447 spdy::SpdySerializedFrame wrapped_get_resp(
6448 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6449 spdy::SpdySerializedFrame body(spdy_util1.ConstructSpdyDataFrame(1, true));
6450 spdy::SpdySerializedFrame wrapped_body(
6451 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6452 spdy::SpdySerializedFrame window_update_get_resp(
6453 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6454 spdy::SpdySerializedFrame window_update_body(
6455 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6456
6457 MockWrite spdy_writes1[] = {
6458 CreateMockWrite(connect, 0),
6459 CreateMockWrite(wrapped_get, 2),
6460 CreateMockWrite(window_update_get_resp, 6),
6461 CreateMockWrite(window_update_body, 7),
6462 };
6463
6464 MockRead spdy_reads1[] = {
6465 CreateMockRead(conn_resp, 1, ASYNC),
6466 MockRead(ASYNC, ERR_IO_PENDING, 3),
6467 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6468 CreateMockRead(wrapped_body, 5, ASYNC),
6469 MockRead(ASYNC, 0, 8),
6470 };
6471
6472 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6473 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6474
6475 // Fetch https://proxy:70/ via HTTP/2. Needs a new SpdyTestUtil, since it uses
6476 // a new pipe.
6477 SpdyTestUtil spdy_util2;
6478 spdy::SpdySerializedFrame req(
6479 spdy_util2.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6480 MockWrite spdy_writes2[] = {CreateMockWrite(req, 0)};
6481
6482 spdy::SpdySerializedFrame resp(
6483 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6484 spdy::SpdySerializedFrame data(spdy_util2.ConstructSpdyDataFrame(1, true));
6485 MockRead spdy_reads2[] = {
6486 CreateMockRead(resp, 1),
6487 CreateMockRead(data, 2),
6488 MockRead(ASYNC, 0, 3),
6489 };
6490 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6491 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6492
6493 SSLSocketDataProvider ssl(ASYNC, OK);
6494 ssl.next_proto = kProtoHTTP2;
6495 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6496 SSLSocketDataProvider ssl2(ASYNC, OK);
6497 ssl2.next_proto = kProtoHTTP2;
6498 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6499 SSLSocketDataProvider ssl3(ASYNC, OK);
6500 ssl3.next_proto = kProtoHTTP2;
6501 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6502
6503 TestCompletionCallback callback;
6504 std::string response_data;
6505
6506 // Make a request using proxy:70 as a HTTP/2 proxy.
6507 capturing_proxy_resolver.set_proxy_server(
6508 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6509 HttpRequestInfo request1;
6510 request1.method = "GET";
6511 request1.url = GURL("https://www.example.org/");
6512 request1.traffic_annotation =
6513 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6514
6515 HttpNetworkTransaction trans1(LOWEST, session.get());
6516 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
6517 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6518
6519 // Allow the SpdyProxyClientSocket's write callback to complete.
6520 base::RunLoop().RunUntilIdle();
6521 // Now allow the read of the response to complete.
6522 spdy_data1.Resume();
6523 rv = callback.WaitForResult();
6524 EXPECT_THAT(rv, IsOk());
6525
6526 const HttpResponseInfo* response = trans1.GetResponseInfo();
6527 ASSERT_TRUE(response);
6528 ASSERT_TRUE(response->headers);
6529 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6530
6531 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6532 EXPECT_EQ(kUploadData, response_data);
6533 RunUntilIdle();
6534
6535 // Make a direct HTTP/2 request to proxy:70.
6536 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6537 HttpRequestInfo request2;
6538 request2.method = "GET";
6539 request2.url = GURL("https://proxy:70/");
6540 request2.traffic_annotation =
6541 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6542 HttpNetworkTransaction trans2(LOWEST, session.get());
6543 EXPECT_THAT(callback.GetResult(trans2.Start(&request2, callback.callback(),
6544 NetLogWithSource())),
6545 IsOk());
6546 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6547}
6548
6549// Same as above, but reverse request order, since the code to check for an
6550// existing session is different for tunnels and direct connections.
6551TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation2) {
6552 // Configure against https proxy server "myproxy:80".
6553 ProxyConfig proxy_config;
6554 proxy_config.set_auto_detect(true);
6555 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6556
6557 CapturingProxyResolver capturing_proxy_resolver;
6558 session_deps_.proxy_resolution_service =
6559 std::make_unique<ProxyResolutionService>(
6560 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6561 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6562 std::make_unique<CapturingProxyResolverFactory>(
6563 &capturing_proxy_resolver),
6564 nullptr);
6565
6566 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6567 // Fetch https://proxy:70/ via HTTP/2.
6568 SpdyTestUtil spdy_util1;
6569 spdy::SpdySerializedFrame req(
6570 spdy_util1.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6571 MockWrite spdy_writes1[] = {CreateMockWrite(req, 0)};
6572
6573 spdy::SpdySerializedFrame resp(
6574 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
6575 spdy::SpdySerializedFrame data(spdy_util1.ConstructSpdyDataFrame(1, true));
6576 MockRead spdy_reads1[] = {
6577 CreateMockRead(resp, 1),
6578 CreateMockRead(data, 2),
6579 MockRead(ASYNC, 0, 3),
6580 };
6581 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6582 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6583
6584 SpdyTestUtil spdy_util2;
6585 // CONNECT to www.example.org:443 via HTTP/2.
6586 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046587 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6588 HostPortPair("www.example.org", 443)));
Matt Menke2436b2f2018-12-11 18:07:116589 // fetch https://www.example.org/ via HTTP/2.
6590 const char kMyUrl[] = "https://www.example.org/";
6591 spdy::SpdySerializedFrame get(spdy_util2.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6592 spdy::SpdySerializedFrame wrapped_get(
6593 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6594 spdy::SpdySerializedFrame conn_resp(
6595 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6596 spdy::SpdySerializedFrame get_resp(
6597 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6598 spdy::SpdySerializedFrame wrapped_get_resp(
6599 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6600 spdy::SpdySerializedFrame body(spdy_util2.ConstructSpdyDataFrame(1, true));
6601 spdy::SpdySerializedFrame wrapped_body(
6602 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6603 spdy::SpdySerializedFrame window_update_get_resp(
6604 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6605 spdy::SpdySerializedFrame window_update_body(
6606 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6607
6608 MockWrite spdy_writes2[] = {
6609 CreateMockWrite(connect, 0),
6610 CreateMockWrite(wrapped_get, 2),
6611 CreateMockWrite(window_update_get_resp, 6),
6612 CreateMockWrite(window_update_body, 7),
6613 };
6614
6615 MockRead spdy_reads2[] = {
6616 CreateMockRead(conn_resp, 1, ASYNC),
6617 MockRead(ASYNC, ERR_IO_PENDING, 3),
6618 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6619 CreateMockRead(wrapped_body, 5, ASYNC),
6620 MockRead(ASYNC, 0, 8),
6621 };
6622
6623 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6624 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6625
6626 SSLSocketDataProvider ssl(ASYNC, OK);
6627 ssl.next_proto = kProtoHTTP2;
6628 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6629 SSLSocketDataProvider ssl2(ASYNC, OK);
6630 ssl2.next_proto = kProtoHTTP2;
6631 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6632 SSLSocketDataProvider ssl3(ASYNC, OK);
6633 ssl3.next_proto = kProtoHTTP2;
6634 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6635
6636 TestCompletionCallback callback;
6637 std::string response_data;
6638
6639 // Make a direct HTTP/2 request to proxy:70.
6640 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6641 HttpRequestInfo request1;
6642 request1.method = "GET";
6643 request1.url = GURL("https://proxy:70/");
6644 request1.traffic_annotation =
6645 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6646 HttpNetworkTransaction trans1(LOWEST, session.get());
6647 EXPECT_THAT(callback.GetResult(trans1.Start(&request1, callback.callback(),
6648 NetLogWithSource())),
6649 IsOk());
6650 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6651 RunUntilIdle();
6652
6653 // Make a request using proxy:70 as a HTTP/2 proxy.
6654 capturing_proxy_resolver.set_proxy_server(
6655 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6656 HttpRequestInfo request2;
6657 request2.method = "GET";
6658 request2.url = GURL("https://www.example.org/");
6659 request2.traffic_annotation =
6660 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6661
6662 HttpNetworkTransaction trans2(LOWEST, session.get());
6663 int rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6664 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6665
6666 // Allow the SpdyProxyClientSocket's write callback to complete.
6667 base::RunLoop().RunUntilIdle();
6668 // Now allow the read of the response to complete.
6669 spdy_data2.Resume();
6670 rv = callback.WaitForResult();
6671 EXPECT_THAT(rv, IsOk());
6672
6673 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
6674 ASSERT_TRUE(response2);
6675 ASSERT_TRUE(response2->headers);
6676 EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
6677
6678 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6679 EXPECT_EQ(kUploadData, response_data);
6680}
6681
[email protected]2df19bb2010-08-25 20:13:466682// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:016683TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:466684 HttpRequestInfo request;
6685 request.method = "GET";
bncce36dca22015-04-21 22:11:236686 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466687 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296688 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:106689 request.traffic_annotation =
6690 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:466691
[email protected]79cb5c12011-09-12 13:12:046692 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496693 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6694 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516695 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076696 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096697 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276698
[email protected]2df19bb2010-08-25 20:13:466699 // Since we have proxy, should use full url
6700 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:166701 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6702 "Host: www.example.org\r\n"
6703 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466704
bnc691fda62016-08-12 00:43:166705 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:236706 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:166707 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6708 "Host: www.example.org\r\n"
6709 "Proxy-Connection: keep-alive\r\n"
6710 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466711 };
6712
6713 // The proxy responds to the GET with a 407, using a persistent
6714 // connection.
6715 MockRead data_reads1[] = {
6716 // No credentials.
6717 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6718 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6719 MockRead("Proxy-Connection: keep-alive\r\n"),
6720 MockRead("Content-Length: 0\r\n\r\n"),
6721
6722 MockRead("HTTP/1.1 200 OK\r\n"),
6723 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6724 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066725 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466726 };
6727
Ryan Sleevib8d7ea02018-05-07 20:01:016728 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:076729 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:066730 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076731 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466732
[email protected]49639fa2011-12-20 23:22:416733 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:466734
bnc691fda62016-08-12 00:43:166735 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506736
bnc691fda62016-08-12 00:43:166737 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:016738 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466739
6740 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016741 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466742
[email protected]58e32bb2013-01-21 18:23:256743 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166744 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256745 TestLoadTimingNotReused(load_timing_info,
6746 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6747
bnc691fda62016-08-12 00:43:166748 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526749 ASSERT_TRUE(response);
6750 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:466751 EXPECT_EQ(407, response->headers->response_code());
6752 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:586753 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
Wojciech Dzierżanowski0950c372019-04-02 19:29:506754 EXPECT_FALSE(response->did_use_http_auth);
[email protected]2df19bb2010-08-25 20:13:466755
[email protected]49639fa2011-12-20 23:22:416756 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:466757
bnc691fda62016-08-12 00:43:166758 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016759 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466760
6761 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016762 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466763
[email protected]58e32bb2013-01-21 18:23:256764 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:166765 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256766 // Retrying with HTTP AUTH is considered to be reusing a socket.
6767 TestLoadTimingReused(load_timing_info);
6768
bnc691fda62016-08-12 00:43:166769 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526770 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:466771
6772 EXPECT_TRUE(response->headers->IsKeepAlive());
6773 EXPECT_EQ(200, response->headers->response_code());
6774 EXPECT_EQ(100, response->headers->GetContentLength());
6775 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Wojciech Dzierżanowski0950c372019-04-02 19:29:506776 EXPECT_TRUE(response->did_use_http_auth);
[email protected]2df19bb2010-08-25 20:13:466777
6778 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:586779 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]2df19bb2010-08-25 20:13:466780}
6781
[email protected]23e482282013-06-14 16:08:026782void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086783 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426784 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086785 request.method = "GET";
bncce36dca22015-04-21 22:11:236786 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106787 request.traffic_annotation =
6788 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086789
[email protected]cb9bf6ca2011-01-28 13:15:276790 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496791 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6792 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096793 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276794
[email protected]c744cf22009-02-27 07:28:086795 // Since we have proxy, should try to establish tunnel.
6796 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176797 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6798 "Host: www.example.org:443\r\n"
6799 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086800 };
6801
6802 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236803 status, MockRead("Content-Length: 10\r\n\r\n"),
6804 // No response body because the test stops reading here.
6805 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086806 };
6807
Ryan Sleevib8d7ea02018-05-07 20:01:016808 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:076809 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086810
[email protected]49639fa2011-12-20 23:22:416811 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086812
bnc691fda62016-08-12 00:43:166813 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506814
tfarina42834112016-09-22 13:38:206815 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086817
6818 rv = callback.WaitForResult();
6819 EXPECT_EQ(expected_status, rv);
6820}
6821
[email protected]23e482282013-06-14 16:08:026822void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236823 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086824 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426825 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086826}
6827
bncd16676a2016-07-20 16:23:016828TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086829 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6830}
6831
bncd16676a2016-07-20 16:23:016832TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086833 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6834}
6835
bncd16676a2016-07-20 16:23:016836TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086837 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6838}
6839
bncd16676a2016-07-20 16:23:016840TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086841 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6842}
6843
bncd16676a2016-07-20 16:23:016844TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086845 ConnectStatusHelper(
6846 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6847}
6848
bncd16676a2016-07-20 16:23:016849TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086850 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6851}
6852
bncd16676a2016-07-20 16:23:016853TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086854 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6855}
6856
bncd16676a2016-07-20 16:23:016857TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086858 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6859}
6860
bncd16676a2016-07-20 16:23:016861TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086862 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6863}
6864
bncd16676a2016-07-20 16:23:016865TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086866 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6867}
6868
bncd16676a2016-07-20 16:23:016869TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086870 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6871}
6872
bncd16676a2016-07-20 16:23:016873TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086874 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6875}
6876
bncd16676a2016-07-20 16:23:016877TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086878 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6879}
6880
bncd16676a2016-07-20 16:23:016881TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086882 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6883}
6884
bncd16676a2016-07-20 16:23:016885TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086886 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6887}
6888
bncd16676a2016-07-20 16:23:016889TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086890 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6891}
6892
bncd16676a2016-07-20 16:23:016893TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376894 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6895}
6896
bncd16676a2016-07-20 16:23:016897TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086898 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6899}
6900
bncd16676a2016-07-20 16:23:016901TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086902 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6903}
6904
bncd16676a2016-07-20 16:23:016905TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086906 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6907}
6908
bncd16676a2016-07-20 16:23:016909TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086910 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6911}
6912
bncd16676a2016-07-20 16:23:016913TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086914 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6915}
6916
bncd16676a2016-07-20 16:23:016917TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086918 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6919}
6920
bncd16676a2016-07-20 16:23:016921TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086922 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6923}
6924
bncd16676a2016-07-20 16:23:016925TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086926 ConnectStatusHelperWithExpectedStatus(
6927 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546928 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086929}
6930
bncd16676a2016-07-20 16:23:016931TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086932 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6933}
6934
bncd16676a2016-07-20 16:23:016935TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086936 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6937}
6938
bncd16676a2016-07-20 16:23:016939TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086940 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6941}
6942
bncd16676a2016-07-20 16:23:016943TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086944 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6945}
6946
bncd16676a2016-07-20 16:23:016947TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086948 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6949}
6950
bncd16676a2016-07-20 16:23:016951TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086952 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6953}
6954
bncd16676a2016-07-20 16:23:016955TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086956 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6957}
6958
bncd16676a2016-07-20 16:23:016959TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086960 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6961}
6962
bncd16676a2016-07-20 16:23:016963TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086964 ConnectStatusHelper(
6965 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6966}
6967
bncd16676a2016-07-20 16:23:016968TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086969 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6970}
6971
bncd16676a2016-07-20 16:23:016972TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086973 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6974}
6975
bncd16676a2016-07-20 16:23:016976TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086977 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6978}
6979
bncd16676a2016-07-20 16:23:016980TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086981 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6982}
6983
bncd16676a2016-07-20 16:23:016984TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086985 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6986}
6987
bncd16676a2016-07-20 16:23:016988TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086989 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6990}
6991
bncd16676a2016-07-20 16:23:016992TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086993 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6994}
6995
[email protected]038e9a32008-10-08 22:40:166996// Test the flow when both the proxy server AND origin server require
6997// authentication. Again, this uses basic auth for both since that is
6998// the simplest to mock.
bncd16676a2016-07-20 16:23:016999TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:277000 HttpRequestInfo request;
7001 request.method = "GET";
bncce36dca22015-04-21 22:11:237002 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107003 request.traffic_annotation =
7004 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277005
[email protected]038e9a32008-10-08 22:40:167006 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497007 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7008 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:097009 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:077010
bnc691fda62016-08-12 00:43:167011 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:167012
[email protected]f9ee6b52008-11-08 06:46:237013 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237014 MockWrite(
7015 "GET http://www.example.org/ HTTP/1.1\r\n"
7016 "Host: www.example.org\r\n"
7017 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237018 };
7019
[email protected]038e9a32008-10-08 22:40:167020 MockRead data_reads1[] = {
7021 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
7022 // Give a couple authenticate options (only the middle one is actually
7023 // supported).
[email protected]22927ad2009-09-21 19:56:197024 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:167025 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7026 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
7027 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7028 // Large content-length -- won't matter, as connection will be reset.
7029 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067030 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:167031 };
7032
bnc691fda62016-08-12 00:43:167033 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:167034 // request we should be issuing -- the final header line contains the
7035 // proxy's credentials.
7036 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237037 MockWrite(
7038 "GET http://www.example.org/ HTTP/1.1\r\n"
7039 "Host: www.example.org\r\n"
7040 "Proxy-Connection: keep-alive\r\n"
7041 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167042 };
7043
7044 // Now the proxy server lets the request pass through to origin server.
7045 // The origin server responds with a 401.
7046 MockRead data_reads2[] = {
7047 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7048 // Note: We are using the same realm-name as the proxy server. This is
7049 // completely valid, as realms are unique across hosts.
7050 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7051 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7052 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067053 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:167054 };
7055
bnc691fda62016-08-12 00:43:167056 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:167057 // the credentials for both the proxy and origin server.
7058 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237059 MockWrite(
7060 "GET http://www.example.org/ HTTP/1.1\r\n"
7061 "Host: www.example.org\r\n"
7062 "Proxy-Connection: keep-alive\r\n"
7063 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
7064 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167065 };
7066
7067 // Lastly we get the desired content.
7068 MockRead data_reads3[] = {
7069 MockRead("HTTP/1.0 200 OK\r\n"),
7070 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7071 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067072 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:167073 };
7074
Ryan Sleevib8d7ea02018-05-07 20:01:017075 StaticSocketDataProvider data1(data_reads1, data_writes1);
7076 StaticSocketDataProvider data2(data_reads2, data_writes2);
7077 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077078 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7079 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7080 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:167081
[email protected]49639fa2011-12-20 23:22:417082 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:167083
tfarina42834112016-09-22 13:38:207084 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167086
7087 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017088 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167089
bnc691fda62016-08-12 00:43:167090 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527091 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587092 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
[email protected]038e9a32008-10-08 22:40:167093
[email protected]49639fa2011-12-20 23:22:417094 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:167095
bnc691fda62016-08-12 00:43:167096 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:017097 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167098
7099 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017100 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167101
bnc691fda62016-08-12 00:43:167102 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527103 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587104 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]038e9a32008-10-08 22:40:167105
[email protected]49639fa2011-12-20 23:22:417106 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:167107
bnc691fda62016-08-12 00:43:167108 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7109 callback3.callback());
robpercival214763f2016-07-01 23:27:017110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167111
7112 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017113 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167114
bnc691fda62016-08-12 00:43:167115 response = trans.GetResponseInfo();
Emily Starkf2c9bbd2019-04-09 17:08:587116 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]038e9a32008-10-08 22:40:167117 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:167118}
[email protected]4ddaf2502008-10-23 18:26:197119
[email protected]ea9dc9a2009-09-05 00:43:327120// For the NTLM implementation using SSPI, we skip the NTLM tests since we
7121// can't hook into its internals to cause it to generate predictable NTLM
7122// authorization headers.
7123#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377124// The NTLM authentication unit tests are based on known test data from the
7125// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
7126// flow rather than the implementation of the NTLM protocol. See net/ntlm
7127// for the implementation and testing of the protocol.
7128//
7129// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:297130
7131// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557132TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:427133 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:247134 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557135 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:107136 request.traffic_annotation =
7137 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547138
7139 // Ensure load is not disrupted by flags which suppress behaviour specific
7140 // to other auth schemes.
7141 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:247142
Zentaro Kavanagh6ccee512017-09-28 18:34:097143 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7144 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097145 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277146
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377147 // Generate the NTLM messages based on known test data.
7148 std::string negotiate_msg;
7149 std::string challenge_msg;
7150 std::string authenticate_msg;
7151 base::Base64Encode(
7152 base::StringPiece(
7153 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247154 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377155 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557156 base::Base64Encode(
7157 base::StringPiece(
7158 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247159 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557160 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377161 base::Base64Encode(
7162 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097163 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557164 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247165 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557166 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377167 &authenticate_msg);
7168
[email protected]3f918782009-02-28 01:29:247169 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557170 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7171 "Host: server\r\n"
7172 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247173 };
7174
7175 MockRead data_reads1[] = {
7176 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047177 // Negotiate and NTLM are often requested together. However, we only want
7178 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7179 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:247180 MockRead("WWW-Authenticate: NTLM\r\n"),
7181 MockRead("Connection: close\r\n"),
7182 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367183 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247184 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:247185 };
7186
7187 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167188 // After restarting with a null identity, this is the
7189 // request we should be issuing -- the final header line contains a Type
7190 // 1 message.
7191 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557192 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167193 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377194 "Authorization: NTLM "),
7195 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247196
bnc691fda62016-08-12 00:43:167197 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377198 // (using correct credentials). The second request continues on the
7199 // same connection.
bnc691fda62016-08-12 00:43:167200 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557201 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167202 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377203 "Authorization: NTLM "),
7204 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247205 };
7206
7207 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:027208 // The origin server responds with a Type 2 message.
7209 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377210 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7211 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027212 MockRead("Content-Type: text/html\r\n\r\n"),
7213 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:247214
Bence Béky1e4ef192017-09-18 19:58:027215 // Lastly we get the desired content.
7216 MockRead("HTTP/1.1 200 OK\r\n"),
7217 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7218 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:247219 };
7220
Ryan Sleevib8d7ea02018-05-07 20:01:017221 StaticSocketDataProvider data1(data_reads1, data_writes1);
7222 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077223 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7224 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:247225
Bence Béky83eb3512017-09-05 12:56:097226 SSLSocketDataProvider ssl1(ASYNC, OK);
7227 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7228 SSLSocketDataProvider ssl2(ASYNC, OK);
7229 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7230
[email protected]49639fa2011-12-20 23:22:417231 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:247232
bnc691fda62016-08-12 00:43:167233 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507234
tfarina42834112016-09-22 13:38:207235 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017236 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247237
7238 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017239 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247240
bnc691fda62016-08-12 00:43:167241 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227242
bnc691fda62016-08-12 00:43:167243 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527244 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587245 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
[email protected]3f918782009-02-28 01:29:247246
[email protected]49639fa2011-12-20 23:22:417247 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:257248
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377249 rv = trans.RestartWithAuth(
7250 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7251 callback2.callback());
robpercival214763f2016-07-01 23:27:017252 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257253
7254 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017255 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257256
bnc691fda62016-08-12 00:43:167257 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257258
bnc691fda62016-08-12 00:43:167259 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527260 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587261 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]10af5fe72011-01-31 16:17:257262
[email protected]49639fa2011-12-20 23:22:417263 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:247264
bnc691fda62016-08-12 00:43:167265 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017266 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247267
[email protected]0757e7702009-03-27 04:00:227268 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017269 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247270
bnc691fda62016-08-12 00:43:167271 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527272 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587273 EXPECT_FALSE(response->auth_challenge.has_value());
Bence Béky1e4ef192017-09-18 19:58:027274 EXPECT_EQ(14, response->headers->GetContentLength());
7275
7276 std::string response_data;
7277 rv = ReadTransaction(&trans, &response_data);
7278 EXPECT_THAT(rv, IsOk());
7279 EXPECT_EQ("Please Login\r\n", response_data);
7280
7281 EXPECT_TRUE(data1.AllReadDataConsumed());
7282 EXPECT_TRUE(data1.AllWriteDataConsumed());
7283 EXPECT_TRUE(data2.AllReadDataConsumed());
7284 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:247285}
7286
[email protected]385a4672009-03-11 22:21:297287// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557288TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:427289 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:297290 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557291 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:107292 request.traffic_annotation =
7293 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:297294
Zentaro Kavanagh6ccee512017-09-28 18:34:097295 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7296 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097297 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277298
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377299 // Generate the NTLM messages based on known test data.
7300 std::string negotiate_msg;
7301 std::string challenge_msg;
7302 std::string authenticate_msg;
7303 base::Base64Encode(
7304 base::StringPiece(
7305 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247306 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377307 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557308 base::Base64Encode(
7309 base::StringPiece(
7310 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247311 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557312 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377313 base::Base64Encode(
7314 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097315 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557316 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247317 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557318 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377319 &authenticate_msg);
7320
7321 // The authenticate message when |kWrongPassword| is sent.
7322 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557323 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
7324 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
7325 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
7326 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
7327 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
7328 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377329
Zentaro Kavanagh1890a3d2018-01-29 19:52:557330 // Sanity check that it's the same length as the correct authenticate message
7331 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377332 ASSERT_EQ(authenticate_msg.length(),
7333 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:557334 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377335
[email protected]385a4672009-03-11 22:21:297336 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557337 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7338 "Host: server\r\n"
7339 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297340 };
7341
7342 MockRead data_reads1[] = {
7343 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047344 // Negotiate and NTLM are often requested together. However, we only want
7345 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7346 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:297347 MockRead("WWW-Authenticate: NTLM\r\n"),
7348 MockRead("Connection: close\r\n"),
7349 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367350 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297351 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297352 };
7353
7354 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167355 // After restarting with a null identity, this is the
7356 // request we should be issuing -- the final header line contains a Type
7357 // 1 message.
7358 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557359 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167360 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377361 "Authorization: NTLM "),
7362 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297363
bnc691fda62016-08-12 00:43:167364 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377365 // (using incorrect credentials). The second request continues on the
7366 // same connection.
bnc691fda62016-08-12 00:43:167367 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557368 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167369 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377370 "Authorization: NTLM "),
7371 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297372 };
7373
7374 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377375 // The origin server responds with a Type 2 message.
7376 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7377 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7378 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
7379 MockRead("Content-Type: text/html\r\n\r\n"),
7380 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297381
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377382 // Wrong password.
7383 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7384 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
7385 MockRead("Content-Length: 42\r\n"),
7386 MockRead("Content-Type: text/html\r\n\r\n"),
7387 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297388 };
7389
7390 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:167391 // After restarting with a null identity, this is the
7392 // request we should be issuing -- the final header line contains a Type
7393 // 1 message.
7394 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557395 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167396 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377397 "Authorization: NTLM "),
7398 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297399
bnc691fda62016-08-12 00:43:167400 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7401 // (the credentials for the origin server). The second request continues
7402 // on the same connection.
7403 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557404 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167405 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377406 "Authorization: NTLM "),
7407 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297408 };
7409
7410 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:027411 // The origin server responds with a Type 2 message.
7412 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377413 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7414 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027415 MockRead("Content-Type: text/html\r\n\r\n"),
7416 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297417
Bence Béky1e4ef192017-09-18 19:58:027418 // Lastly we get the desired content.
7419 MockRead("HTTP/1.1 200 OK\r\n"),
7420 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7421 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:297422 };
7423
Ryan Sleevib8d7ea02018-05-07 20:01:017424 StaticSocketDataProvider data1(data_reads1, data_writes1);
7425 StaticSocketDataProvider data2(data_reads2, data_writes2);
7426 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077427 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7428 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7429 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:297430
Bence Béky83eb3512017-09-05 12:56:097431 SSLSocketDataProvider ssl1(ASYNC, OK);
7432 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7433 SSLSocketDataProvider ssl2(ASYNC, OK);
7434 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7435 SSLSocketDataProvider ssl3(ASYNC, OK);
7436 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
7437
[email protected]49639fa2011-12-20 23:22:417438 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:297439
bnc691fda62016-08-12 00:43:167440 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507441
tfarina42834112016-09-22 13:38:207442 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017443 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297444
7445 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017446 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297447
bnc691fda62016-08-12 00:43:167448 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:297449
bnc691fda62016-08-12 00:43:167450 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527451 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587452 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
[email protected]385a4672009-03-11 22:21:297453
[email protected]49639fa2011-12-20 23:22:417454 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:297455
[email protected]0757e7702009-03-27 04:00:227456 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377457 rv = trans.RestartWithAuth(
7458 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
7459 callback2.callback());
robpercival214763f2016-07-01 23:27:017460 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297461
[email protected]10af5fe72011-01-31 16:17:257462 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017463 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297464
bnc691fda62016-08-12 00:43:167465 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417466 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167467 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017468 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257469 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017470 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167471 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227472
bnc691fda62016-08-12 00:43:167473 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527474 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587475 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
[email protected]0757e7702009-03-27 04:00:227476
[email protected]49639fa2011-12-20 23:22:417477 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:227478
7479 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377480 rv = trans.RestartWithAuth(
7481 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7482 callback4.callback());
robpercival214763f2016-07-01 23:27:017483 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257484
7485 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:017486 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257487
bnc691fda62016-08-12 00:43:167488 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257489
[email protected]49639fa2011-12-20 23:22:417490 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:257491
7492 // One more roundtrip
bnc691fda62016-08-12 00:43:167493 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:017494 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227495
7496 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:017497 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:227498
bnc691fda62016-08-12 00:43:167499 response = trans.GetResponseInfo();
Emily Starkf2c9bbd2019-04-09 17:08:587500 EXPECT_FALSE(response->auth_challenge.has_value());
Bence Béky1e4ef192017-09-18 19:58:027501 EXPECT_EQ(14, response->headers->GetContentLength());
7502
7503 std::string response_data;
7504 rv = ReadTransaction(&trans, &response_data);
7505 EXPECT_THAT(rv, IsOk());
7506 EXPECT_EQ("Please Login\r\n", response_data);
7507
7508 EXPECT_TRUE(data1.AllReadDataConsumed());
7509 EXPECT_TRUE(data1.AllWriteDataConsumed());
7510 EXPECT_TRUE(data2.AllReadDataConsumed());
7511 EXPECT_TRUE(data2.AllWriteDataConsumed());
7512 EXPECT_TRUE(data3.AllReadDataConsumed());
7513 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:297514}
Bence Béky83eb3512017-09-05 12:56:097515
Bence Béky3238f2e12017-09-22 22:44:497516// Server requests NTLM authentication, which is not supported over HTTP/2.
7517// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:097518TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:097519 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7520 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:097521
Zentaro Kavanagh1890a3d2018-01-29 19:52:557522 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:097523
7524 HttpRequestInfo request;
7525 request.method = "GET";
7526 request.url = GURL(kUrl);
Ramin Halavatib5e433e2018-02-07 07:41:107527 request.traffic_annotation =
7528 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:097529
7530 // First request without credentials.
Ryan Hamilton0239aac2018-05-19 00:03:137531 spdy::SpdyHeaderBlock request_headers0(
7532 spdy_util_.ConstructGetHeaderBlock(kUrl));
7533 spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
Bence Béky83eb3512017-09-05 12:56:097534 1, std::move(request_headers0), LOWEST, true));
7535
Ryan Hamilton0239aac2018-05-19 00:03:137536 spdy::SpdyHeaderBlock response_headers0;
7537 response_headers0[spdy::kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:097538 response_headers0["www-authenticate"] = "NTLM";
Ryan Hamilton0239aac2018-05-19 00:03:137539 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Béky83eb3512017-09-05 12:56:097540 1, std::move(response_headers0), true));
7541
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377542 // Stream 1 is closed.
7543 spdy_util_.UpdateWithStreamDestruction(1);
7544
7545 // Generate the NTLM messages based on known test data.
7546 std::string negotiate_msg;
7547 std::string challenge_msg;
7548 std::string authenticate_msg;
7549 base::Base64Encode(
7550 base::StringPiece(
7551 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247552 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377553 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557554 base::Base64Encode(
7555 base::StringPiece(
7556 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247557 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557558 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377559 base::Base64Encode(
7560 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097561 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557562 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247563 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557564 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377565 &authenticate_msg);
7566
7567 // Retry with authorization header.
Ryan Hamilton0239aac2018-05-19 00:03:137568 spdy::SpdyHeaderBlock request_headers1(
7569 spdy_util_.ConstructGetHeaderBlock(kUrl));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377570 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
Ryan Hamilton0239aac2018-05-19 00:03:137571 spdy::SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377572 3, std::move(request_headers1), LOWEST, true));
7573
Ryan Hamilton0239aac2018-05-19 00:03:137574 spdy::SpdySerializedFrame rst(
7575 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377576
Bence Béky3238f2e12017-09-22 22:44:497577 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
7578 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:097579
7580 // Retry yet again using HTTP/1.1.
7581 MockWrite writes1[] = {
7582 // After restarting with a null identity, this is the
7583 // request we should be issuing -- the final header line contains a Type
7584 // 1 message.
7585 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557586 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097587 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377588 "Authorization: NTLM "),
7589 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097590
7591 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7592 // (the credentials for the origin server). The second request continues
7593 // on the same connection.
7594 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557595 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097596 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377597 "Authorization: NTLM "),
7598 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097599 };
7600
7601 MockRead reads1[] = {
7602 // The origin server responds with a Type 2 message.
7603 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377604 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7605 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:097606 MockRead("Content-Type: text/html\r\n\r\n"),
7607 MockRead("You are not authorized to view this page\r\n"),
7608
7609 // Lastly we get the desired content.
7610 MockRead("HTTP/1.1 200 OK\r\n"),
7611 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027612 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:097613 };
Ryan Sleevib8d7ea02018-05-07 20:01:017614 SequencedSocketData data0(reads0, writes0);
7615 StaticSocketDataProvider data1(reads1, writes1);
Bence Béky83eb3512017-09-05 12:56:097616 session_deps_.socket_factory->AddSocketDataProvider(&data0);
7617 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7618
7619 SSLSocketDataProvider ssl0(ASYNC, OK);
7620 ssl0.next_proto = kProtoHTTP2;
7621 SSLSocketDataProvider ssl1(ASYNC, OK);
7622 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
7623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7624
7625 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7626 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7627
7628 TestCompletionCallback callback1;
7629 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
7630 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7631
7632 rv = callback1.WaitForResult();
7633 EXPECT_THAT(rv, IsOk());
7634
7635 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7636
7637 const HttpResponseInfo* response = trans.GetResponseInfo();
7638 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587639 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
Bence Béky83eb3512017-09-05 12:56:097640
7641 TestCompletionCallback callback2;
7642
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377643 rv = trans.RestartWithAuth(
7644 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7645 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:097646 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7647
7648 rv = callback2.WaitForResult();
7649 EXPECT_THAT(rv, IsOk());
7650
7651 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7652
7653 response = trans.GetResponseInfo();
7654 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587655 EXPECT_FALSE(response->auth_challenge.has_value());
Bence Béky83eb3512017-09-05 12:56:097656
7657 TestCompletionCallback callback3;
7658
7659 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
7660 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7661
7662 rv = callback3.WaitForResult();
7663 EXPECT_THAT(rv, IsOk());
7664
7665 response = trans.GetResponseInfo();
7666 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587667 EXPECT_FALSE(response->auth_challenge.has_value());
Bence Béky1e4ef192017-09-18 19:58:027668 EXPECT_EQ(14, response->headers->GetContentLength());
7669
7670 std::string response_data;
7671 rv = ReadTransaction(&trans, &response_data);
7672 EXPECT_THAT(rv, IsOk());
7673 EXPECT_EQ("Please Login\r\n", response_data);
7674
7675 EXPECT_TRUE(data0.AllReadDataConsumed());
7676 EXPECT_TRUE(data0.AllWriteDataConsumed());
7677 EXPECT_TRUE(data1.AllReadDataConsumed());
7678 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:097679}
David Benjamin5cb91132018-04-06 05:54:497680
7681// Test that, if we have an NTLM proxy and the origin resets the connection, we
7682// do no retry forever checking for TLS version interference. This is a
7683// regression test for https://crbug.com/823387.
7684TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
7685 // The NTLM test data expects the proxy to be named 'server'. The origin is
7686 // https://origin/.
7687 session_deps_.proxy_resolution_service =
7688 ProxyResolutionService::CreateFixedFromPacResult(
7689 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
7690
7691 SSLConfig config;
David Benjamin5cb91132018-04-06 05:54:497692 session_deps_.ssl_config_service =
Ryan Sleevib8449e02018-07-15 04:31:077693 std::make_unique<TestSSLConfigService>(config);
David Benjamin5cb91132018-04-06 05:54:497694
7695 HttpRequestInfo request;
7696 request.method = "GET";
7697 request.url = GURL("https://origin/");
7698 request.traffic_annotation =
7699 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7700
7701 // Ensure load is not disrupted by flags which suppress behaviour specific
7702 // to other auth schemes.
7703 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7704
7705 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7706 MockGetMSTime, MockGenerateRandom, MockGetHostName);
7707 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7708
7709 // Generate the NTLM messages based on known test data.
7710 std::string negotiate_msg;
7711 std::string challenge_msg;
7712 std::string authenticate_msg;
7713 base::Base64Encode(
7714 base::StringPiece(
7715 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247716 base::size(ntlm::test::kExpectedNegotiateMsg)),
David Benjamin5cb91132018-04-06 05:54:497717 &negotiate_msg);
7718 base::Base64Encode(
7719 base::StringPiece(
7720 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247721 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
David Benjamin5cb91132018-04-06 05:54:497722 &challenge_msg);
7723 base::Base64Encode(
7724 base::StringPiece(
7725 reinterpret_cast<const char*>(
7726 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247727 base::size(
David Benjamin5cb91132018-04-06 05:54:497728 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
7729 &authenticate_msg);
7730
7731 MockWrite data_writes[] = {
7732 // The initial CONNECT request.
7733 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7734 "Host: origin:443\r\n"
7735 "Proxy-Connection: keep-alive\r\n\r\n"),
7736
7737 // After restarting with an identity.
7738 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7739 "Host: origin:443\r\n"
7740 "Proxy-Connection: keep-alive\r\n"
7741 "Proxy-Authorization: NTLM "),
7742 MockWrite(negotiate_msg.c_str()),
7743 // End headers.
7744 MockWrite("\r\n\r\n"),
7745
7746 // The second restart.
7747 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7748 "Host: origin:443\r\n"
7749 "Proxy-Connection: keep-alive\r\n"
7750 "Proxy-Authorization: NTLM "),
7751 MockWrite(authenticate_msg.c_str()),
7752 // End headers.
7753 MockWrite("\r\n\r\n"),
7754 };
7755
7756 MockRead data_reads[] = {
7757 // The initial NTLM response.
7758 MockRead("HTTP/1.1 407 Access Denied\r\n"
7759 "Content-Length: 0\r\n"
7760 "Proxy-Authenticate: NTLM\r\n\r\n"),
7761
7762 // The NTLM challenge message.
7763 MockRead("HTTP/1.1 407 Access Denied\r\n"
7764 "Content-Length: 0\r\n"
7765 "Proxy-Authenticate: NTLM "),
7766 MockRead(challenge_msg.c_str()),
7767 // End headers.
7768 MockRead("\r\n\r\n"),
7769
7770 // Finally the tunnel is established.
7771 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
7772 };
7773
Ryan Sleevib8d7ea02018-05-07 20:01:017774 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497775 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
Ryan Sleevib8d7ea02018-05-07 20:01:017776 StaticSocketDataProvider data2(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497777 SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
Steven Valdez0ef94d02018-11-19 23:28:137778 data_ssl2.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
David Benjamin5cb91132018-04-06 05:54:497779 session_deps_.socket_factory->AddSocketDataProvider(&data);
7780 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
7781 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7782 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
7783
7784 // Start the transaction. The proxy responds with an NTLM authentication
7785 // request.
7786 TestCompletionCallback callback;
7787 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7788 int rv = callback.GetResult(
7789 trans.Start(&request, callback.callback(), NetLogWithSource()));
7790
7791 EXPECT_THAT(rv, IsOk());
7792 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7793 const HttpResponseInfo* response = trans.GetResponseInfo();
7794 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587795 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge));
David Benjamin5cb91132018-04-06 05:54:497796
7797 // Configure credentials. The proxy responds with the challenge message.
7798 rv = callback.GetResult(trans.RestartWithAuth(
7799 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7800 callback.callback()));
7801 EXPECT_THAT(rv, IsOk());
7802 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7803 response = trans.GetResponseInfo();
7804 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587805 EXPECT_FALSE(response->auth_challenge.has_value());
David Benjamin5cb91132018-04-06 05:54:497806
7807 // Restart once more. The tunnel will be established and the the SSL handshake
7808 // will reset. The TLS 1.3 version interference probe will then kick in and
7809 // restart the process. The proxy responds with another NTLM authentiation
7810 // request, but we don't need to provide credentials as the cached ones work/
7811 rv = callback.GetResult(
7812 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7813 EXPECT_THAT(rv, IsOk());
7814 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7815 response = trans.GetResponseInfo();
7816 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587817 EXPECT_FALSE(response->auth_challenge.has_value());
David Benjamin5cb91132018-04-06 05:54:497818
7819 // The proxy responds with the NTLM challenge message.
7820 rv = callback.GetResult(
7821 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7822 EXPECT_THAT(rv, IsOk());
7823 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7824 response = trans.GetResponseInfo();
7825 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587826 EXPECT_FALSE(response->auth_challenge.has_value());
David Benjamin5cb91132018-04-06 05:54:497827
7828 // Send the NTLM authenticate message. The tunnel is established and the
7829 // handshake resets again. We should not retry again.
7830 rv = callback.GetResult(
7831 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7832 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
7833}
7834
[email protected]ea9dc9a2009-09-05 00:43:327835#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:297836
[email protected]4ddaf2502008-10-23 18:26:197837// Test reading a server response which has only headers, and no body.
7838// After some maximum number of bytes is consumed, the transaction should
7839// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:017840TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:427841 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:197842 request.method = "GET";
bncce36dca22015-04-21 22:11:237843 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107844 request.traffic_annotation =
7845 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:197846
danakj1fd259a02016-04-16 03:17:097847 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167848 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277849
[email protected]b75b7b2f2009-10-06 00:54:537850 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:437851 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:537852 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:197853
7854 MockRead data_reads[] = {
7855 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:067856 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:197857 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:067858 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:197859 };
Ryan Sleevib8d7ea02018-05-07 20:01:017860 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077861 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:197862
[email protected]49639fa2011-12-20 23:22:417863 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:197864
tfarina42834112016-09-22 13:38:207865 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017866 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:197867
7868 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017869 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197870}
[email protected]f4e426b2008-11-05 00:24:497871
7872// Make sure that we don't try to reuse a TCPClientSocket when failing to
7873// establish tunnel.
7874// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017875TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277876 HttpRequestInfo request;
7877 request.method = "GET";
bncce36dca22015-04-21 22:11:237878 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107879 request.traffic_annotation =
7880 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277881
[email protected]f4e426b2008-11-05 00:24:497882 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497883 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7884 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017885
danakj1fd259a02016-04-16 03:17:097886 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497887
bnc87dcefc2017-05-25 12:47:587888 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197889 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497890
[email protected]f4e426b2008-11-05 00:24:497891 // Since we have proxy, should try to establish tunnel.
7892 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177893 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7894 "Host: www.example.org:443\r\n"
7895 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497896 };
7897
[email protected]77848d12008-11-14 00:00:227898 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497899 // connection. Usually a proxy would return 501 (not implemented),
7900 // or 200 (tunnel established).
7901 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237902 MockRead("HTTP/1.1 404 Not Found\r\n"),
7903 MockRead("Content-Length: 10\r\n\r\n"),
7904 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497905 };
7906
Ryan Sleevib8d7ea02018-05-07 20:01:017907 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:077908 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497909
[email protected]49639fa2011-12-20 23:22:417910 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497911
tfarina42834112016-09-22 13:38:207912 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017913 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497914
7915 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017916 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497917
[email protected]b4404c02009-04-10 16:38:527918 // Empty the current queue. This is necessary because idle sockets are
7919 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557920 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527921
[email protected]f4e426b2008-11-05 00:24:497922 // We now check to make sure the TCPClientSocket was not added back to
7923 // the pool.
[email protected]90499482013-06-01 00:39:507924 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497925 trans.reset();
fdoray92e35a72016-06-10 15:54:557926 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497927 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507928 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497929}
[email protected]372d34a2008-11-05 21:30:517930
[email protected]1b157c02009-04-21 01:55:407931// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017932TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427933 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407934 request.method = "GET";
bncce36dca22015-04-21 22:11:237935 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107936 request.traffic_annotation =
7937 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407938
danakj1fd259a02016-04-16 03:17:097939 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277940
bnc691fda62016-08-12 00:43:167941 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277942
[email protected]1b157c02009-04-21 01:55:407943 MockRead data_reads[] = {
7944 // A part of the response body is received with the response headers.
7945 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7946 // The rest of the response body is received in two parts.
7947 MockRead("lo"),
7948 MockRead(" world"),
7949 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067950 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407951 };
7952
Ryan Sleevib8d7ea02018-05-07 20:01:017953 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077954 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407955
[email protected]49639fa2011-12-20 23:22:417956 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407957
tfarina42834112016-09-22 13:38:207958 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407960
7961 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017962 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407963
bnc691fda62016-08-12 00:43:167964 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527965 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407966
wezca1070932016-05-26 20:30:527967 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407968 std::string status_line = response->headers->GetStatusLine();
7969 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7970
[email protected]90499482013-06-01 00:39:507971 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407972
7973 std::string response_data;
bnc691fda62016-08-12 00:43:167974 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017975 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407976 EXPECT_EQ("hello world", response_data);
7977
7978 // Empty the current queue. This is necessary because idle sockets are
7979 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557980 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407981
7982 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507983 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407984}
7985
[email protected]76a505b2010-08-25 06:23:007986// Make sure that we recycle a SSL socket after reading all of the response
7987// body.
bncd16676a2016-07-20 16:23:017988TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007989 HttpRequestInfo request;
7990 request.method = "GET";
bncce36dca22015-04-21 22:11:237991 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107992 request.traffic_annotation =
7993 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007994
7995 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237996 MockWrite(
7997 "GET / HTTP/1.1\r\n"
7998 "Host: www.example.org\r\n"
7999 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:008000 };
8001
8002 MockRead data_reads[] = {
8003 MockRead("HTTP/1.1 200 OK\r\n"),
8004 MockRead("Content-Length: 11\r\n\r\n"),
8005 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068006 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:008007 };
8008
[email protected]8ddf8322012-02-23 18:08:068009 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078010 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:008011
Ryan Sleevib8d7ea02018-05-07 20:01:018012 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078013 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:008014
[email protected]49639fa2011-12-20 23:22:418015 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008016
danakj1fd259a02016-04-16 03:17:098017 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168018 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008019
tfarina42834112016-09-22 13:38:208020 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008021
robpercival214763f2016-07-01 23:27:018022 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8023 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008024
bnc691fda62016-08-12 00:43:168025 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528026 ASSERT_TRUE(response);
8027 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008028 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8029
[email protected]90499482013-06-01 00:39:508030 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008031
8032 std::string response_data;
bnc691fda62016-08-12 00:43:168033 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018034 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008035 EXPECT_EQ("hello world", response_data);
8036
8037 // Empty the current queue. This is necessary because idle sockets are
8038 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558039 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008040
8041 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238042 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008043}
8044
8045// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
8046// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:018047TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:008048 HttpRequestInfo request;
8049 request.method = "GET";
bncce36dca22015-04-21 22:11:238050 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108051 request.traffic_annotation =
8052 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:008053
8054 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238055 MockWrite(
8056 "GET / HTTP/1.1\r\n"
8057 "Host: www.example.org\r\n"
8058 "Connection: keep-alive\r\n\r\n"),
8059 MockWrite(
8060 "GET / HTTP/1.1\r\n"
8061 "Host: www.example.org\r\n"
8062 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:008063 };
8064
8065 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:428066 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8067 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:008068
[email protected]8ddf8322012-02-23 18:08:068069 SSLSocketDataProvider ssl(ASYNC, OK);
8070 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078071 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8072 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:008073
Ryan Sleevib8d7ea02018-05-07 20:01:018074 StaticSocketDataProvider data(data_reads, data_writes);
8075 StaticSocketDataProvider data2(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078076 session_deps_.socket_factory->AddSocketDataProvider(&data);
8077 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:008078
[email protected]49639fa2011-12-20 23:22:418079 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008080
danakj1fd259a02016-04-16 03:17:098081 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:588082 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198083 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008084
tfarina42834112016-09-22 13:38:208085 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008086
robpercival214763f2016-07-01 23:27:018087 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8088 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008089
8090 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528091 ASSERT_TRUE(response);
8092 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008093 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8094
[email protected]90499482013-06-01 00:39:508095 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008096
8097 std::string response_data;
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 // Now start the second transaction, which should reuse the previous socket.
8110
bnc87dcefc2017-05-25 12:47:588111 trans =
Jeremy Roman0579ed62017-08-29 15:56:198112 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008113
tfarina42834112016-09-22 13:38:208114 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008115
robpercival214763f2016-07-01 23:27:018116 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8117 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008118
8119 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528120 ASSERT_TRUE(response);
8121 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008122 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8123
[email protected]90499482013-06-01 00:39:508124 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008125
8126 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018127 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008128 EXPECT_EQ("hello world", response_data);
8129
8130 // Empty the current queue. This is necessary because idle sockets are
8131 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558132 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008133
8134 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238135 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008136}
8137
maksim.sisov0adf8592016-07-15 06:25:568138// Grab a socket, use it, and put it back into the pool. Then, make
8139// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018140TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568141 HttpRequestInfo request;
8142 request.method = "GET";
8143 request.url = GURL("http://www.example.org/");
8144 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108145 request.traffic_annotation =
8146 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568147
8148 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8149
bnc691fda62016-08-12 00:43:168150 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568151
8152 MockRead data_reads[] = {
8153 // A part of the response body is received with the response headers.
8154 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8155 // The rest of the response body is received in two parts.
8156 MockRead("lo"), MockRead(" world"),
8157 MockRead("junk"), // Should not be read!!
8158 MockRead(SYNCHRONOUS, OK),
8159 };
8160
Ryan Sleevib8d7ea02018-05-07 20:01:018161 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
maksim.sisov0adf8592016-07-15 06:25:568162 session_deps_.socket_factory->AddSocketDataProvider(&data);
8163
8164 TestCompletionCallback callback;
8165
tfarina42834112016-09-22 13:38:208166 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568167 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8168
8169 EXPECT_THAT(callback.GetResult(rv), IsOk());
8170
bnc691fda62016-08-12 00:43:168171 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568172 ASSERT_TRUE(response);
8173 EXPECT_TRUE(response->headers);
8174 std::string status_line = response->headers->GetStatusLine();
8175 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8176
8177 // Make memory critical notification and ensure the transaction still has been
8178 // operating right.
8179 base::MemoryPressureListener::NotifyMemoryPressure(
8180 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8181 base::RunLoop().RunUntilIdle();
8182
8183 // Socket should not be flushed as long as it is not idle.
8184 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8185
8186 std::string response_data;
bnc691fda62016-08-12 00:43:168187 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568188 EXPECT_THAT(rv, IsOk());
8189 EXPECT_EQ("hello world", response_data);
8190
8191 // Empty the current queue. This is necessary because idle sockets are
8192 // added to the connection pool asynchronously with a PostTask.
8193 base::RunLoop().RunUntilIdle();
8194
8195 // We now check to make sure the socket was added back to the pool.
8196 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8197
8198 // Idle sockets should be flushed now.
8199 base::MemoryPressureListener::NotifyMemoryPressure(
8200 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8201 base::RunLoop().RunUntilIdle();
8202
8203 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8204}
8205
yucliu48f235d2018-01-11 00:59:558206// Disable idle socket closing on memory pressure.
8207// Grab a socket, use it, and put it back into the pool. Then, make
8208// low memory notification and ensure the socket pool is NOT flushed.
8209TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
8210 HttpRequestInfo request;
8211 request.method = "GET";
8212 request.url = GURL("http://www.example.org/");
8213 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108214 request.traffic_annotation =
8215 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:558216
8217 // Disable idle socket closing on memory pressure.
8218 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
8219 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8220
8221 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8222
8223 MockRead data_reads[] = {
8224 // A part of the response body is received with the response headers.
8225 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8226 // The rest of the response body is received in two parts.
8227 MockRead("lo"), MockRead(" world"),
8228 MockRead("junk"), // Should not be read!!
8229 MockRead(SYNCHRONOUS, OK),
8230 };
8231
Ryan Sleevib8d7ea02018-05-07 20:01:018232 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
yucliu48f235d2018-01-11 00:59:558233 session_deps_.socket_factory->AddSocketDataProvider(&data);
8234
8235 TestCompletionCallback callback;
8236
8237 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
8238 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8239
8240 EXPECT_THAT(callback.GetResult(rv), IsOk());
8241
8242 const HttpResponseInfo* response = trans.GetResponseInfo();
8243 ASSERT_TRUE(response);
8244 EXPECT_TRUE(response->headers);
8245 std::string status_line = response->headers->GetStatusLine();
8246 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8247
8248 // Make memory critical notification and ensure the transaction still has been
8249 // operating right.
8250 base::MemoryPressureListener::NotifyMemoryPressure(
8251 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8252 base::RunLoop().RunUntilIdle();
8253
8254 // Socket should not be flushed as long as it is not idle.
8255 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8256
8257 std::string response_data;
8258 rv = ReadTransaction(&trans, &response_data);
8259 EXPECT_THAT(rv, IsOk());
8260 EXPECT_EQ("hello world", response_data);
8261
8262 // Empty the current queue. This is necessary because idle sockets are
8263 // added to the connection pool asynchronously with a PostTask.
8264 base::RunLoop().RunUntilIdle();
8265
8266 // We now check to make sure the socket was added back to the pool.
8267 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8268
8269 // Idle sockets should NOT be flushed on moderate memory pressure.
8270 base::MemoryPressureListener::NotifyMemoryPressure(
8271 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
8272 base::RunLoop().RunUntilIdle();
8273
8274 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8275
8276 // Idle sockets should NOT be flushed on critical memory pressure.
8277 base::MemoryPressureListener::NotifyMemoryPressure(
8278 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8279 base::RunLoop().RunUntilIdle();
8280
8281 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8282}
8283
maksim.sisov0adf8592016-07-15 06:25:568284// Grab an SSL socket, use it, and put it back into the pool. Then, make
8285// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018286TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568287 HttpRequestInfo request;
8288 request.method = "GET";
8289 request.url = GURL("https://www.example.org/");
8290 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108291 request.traffic_annotation =
8292 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568293
8294 MockWrite data_writes[] = {
8295 MockWrite("GET / HTTP/1.1\r\n"
8296 "Host: www.example.org\r\n"
8297 "Connection: keep-alive\r\n\r\n"),
8298 };
8299
8300 MockRead data_reads[] = {
8301 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8302 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
8303
8304 SSLSocketDataProvider ssl(ASYNC, OK);
8305 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8306
Ryan Sleevib8d7ea02018-05-07 20:01:018307 StaticSocketDataProvider data(data_reads, data_writes);
maksim.sisov0adf8592016-07-15 06:25:568308 session_deps_.socket_factory->AddSocketDataProvider(&data);
8309
8310 TestCompletionCallback callback;
8311
8312 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168313 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568314
Matt Menke9d5e2c92019-02-05 01:42:238315 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
tfarina42834112016-09-22 13:38:208316 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568317
8318 EXPECT_THAT(callback.GetResult(rv), IsOk());
8319
bnc691fda62016-08-12 00:43:168320 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568321 ASSERT_TRUE(response);
8322 ASSERT_TRUE(response->headers);
8323 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8324
8325 // Make memory critical notification and ensure the transaction still has been
8326 // operating right.
8327 base::MemoryPressureListener::NotifyMemoryPressure(
8328 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8329 base::RunLoop().RunUntilIdle();
8330
Matt Menke9d5e2c92019-02-05 01:42:238331 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568332
8333 std::string response_data;
bnc691fda62016-08-12 00:43:168334 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568335 EXPECT_THAT(rv, IsOk());
8336 EXPECT_EQ("hello world", response_data);
8337
8338 // Empty the current queue. This is necessary because idle sockets are
8339 // added to the connection pool asynchronously with a PostTask.
8340 base::RunLoop().RunUntilIdle();
8341
8342 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238343 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568344
8345 // Make memory notification once again and ensure idle socket is closed.
8346 base::MemoryPressureListener::NotifyMemoryPressure(
8347 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8348 base::RunLoop().RunUntilIdle();
8349
Matt Menke9d5e2c92019-02-05 01:42:238350 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568351}
8352
[email protected]b4404c02009-04-10 16:38:528353// Make sure that we recycle a socket after a zero-length response.
8354// http://crbug.com/9880
bncd16676a2016-07-20 16:23:018355TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:428356 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:528357 request.method = "GET";
bncce36dca22015-04-21 22:11:238358 request.url = GURL(
8359 "http://www.example.org/csi?v=3&s=web&action=&"
8360 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
8361 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
8362 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e2018-02-07 07:41:108363 request.traffic_annotation =
8364 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:528365
danakj1fd259a02016-04-16 03:17:098366 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278367
[email protected]b4404c02009-04-10 16:38:528368 MockRead data_reads[] = {
8369 MockRead("HTTP/1.1 204 No Content\r\n"
8370 "Content-Length: 0\r\n"
8371 "Content-Type: text/html\r\n\r\n"),
8372 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:068373 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:528374 };
8375
Ryan Sleevib8d7ea02018-05-07 20:01:018376 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:078377 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:528378
mmenkecc2298e2015-12-07 18:20:188379 // Transaction must be created after the MockReads, so it's destroyed before
8380 // them.
bnc691fda62016-08-12 00:43:168381 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:188382
[email protected]49639fa2011-12-20 23:22:418383 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:528384
tfarina42834112016-09-22 13:38:208385 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018386 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:528387
8388 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018389 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528390
bnc691fda62016-08-12 00:43:168391 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528392 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:528393
wezca1070932016-05-26 20:30:528394 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:528395 std::string status_line = response->headers->GetStatusLine();
8396 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
8397
[email protected]90499482013-06-01 00:39:508398 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528399
8400 std::string response_data;
bnc691fda62016-08-12 00:43:168401 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018402 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528403 EXPECT_EQ("", response_data);
8404
8405 // Empty the current queue. This is necessary because idle sockets are
8406 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558407 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:528408
8409 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508410 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528411}
8412
bncd16676a2016-07-20 16:23:018413TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:098414 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:228415 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:198416 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:228417 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:278418
[email protected]1c773ea12009-04-28 19:58:428419 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:518420 // Transaction 1: a GET request that succeeds. The socket is recycled
8421 // after use.
8422 request[0].method = "GET";
8423 request[0].url = GURL("http://www.google.com/");
8424 request[0].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108425 request[0].traffic_annotation =
8426 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518427 // Transaction 2: a POST request. Reuses the socket kept alive from
8428 // transaction 1. The first attempts fails when writing the POST data.
8429 // This causes the transaction to retry with a new socket. The second
8430 // attempt succeeds.
8431 request[1].method = "POST";
8432 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:278433 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:518434 request[1].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108435 request[1].traffic_annotation =
8436 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518437
danakj1fd259a02016-04-16 03:17:098438 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:518439
8440 // The first socket is used for transaction 1 and the first attempt of
8441 // transaction 2.
8442
8443 // The response of transaction 1.
8444 MockRead data_reads1[] = {
8445 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
8446 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068447 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518448 };
8449 // The mock write results of transaction 1 and the first attempt of
8450 // transaction 2.
8451 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:068452 MockWrite(SYNCHRONOUS, 64), // GET
8453 MockWrite(SYNCHRONOUS, 93), // POST
8454 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:518455 };
Ryan Sleevib8d7ea02018-05-07 20:01:018456 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:518457
8458 // The second socket is used for the second attempt of transaction 2.
8459
8460 // The response of transaction 2.
8461 MockRead data_reads2[] = {
8462 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
8463 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:068464 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518465 };
8466 // The mock write results of the second attempt of transaction 2.
8467 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:068468 MockWrite(SYNCHRONOUS, 93), // POST
8469 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:518470 };
Ryan Sleevib8d7ea02018-05-07 20:01:018471 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:518472
[email protected]bb88e1d32013-05-03 23:11:078473 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8474 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:518475
thestig9d3bb0c2015-01-24 00:49:518476 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:518477 "hello world", "welcome"
8478 };
8479
8480 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:168481 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:518482
[email protected]49639fa2011-12-20 23:22:418483 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:518484
tfarina42834112016-09-22 13:38:208485 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018486 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:518487
8488 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018489 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518490
bnc691fda62016-08-12 00:43:168491 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528492 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:518493
wezca1070932016-05-26 20:30:528494 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:518495 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8496
8497 std::string response_data;
bnc691fda62016-08-12 00:43:168498 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018499 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518500 EXPECT_EQ(kExpectedResponseData[i], response_data);
8501 }
8502}
[email protected]f9ee6b52008-11-08 06:46:238503
8504// Test the request-challenge-retry sequence for basic auth when there is
8505// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:168506// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:018507TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:428508 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238509 request.method = "GET";
bncce36dca22015-04-21 22:11:238510 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:418511 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:108512 request.traffic_annotation =
8513 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:298514
danakj1fd259a02016-04-16 03:17:098515 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168516 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278517
[email protected]a97cca42009-08-14 01:00:298518 // The password contains an escaped character -- for this test to pass it
8519 // will need to be unescaped by HttpNetworkTransaction.
8520 EXPECT_EQ("b%40r", request.url.password());
8521
[email protected]f9ee6b52008-11-08 06:46:238522 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238523 MockWrite(
8524 "GET / HTTP/1.1\r\n"
8525 "Host: www.example.org\r\n"
8526 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238527 };
8528
8529 MockRead data_reads1[] = {
8530 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8531 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8532 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068533 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238534 };
8535
[email protected]2262e3a2012-05-22 16:08:168536 // After the challenge above, the transaction will be restarted using the
8537 // identity from the url (foo, b@r) to answer the challenge.
8538 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238539 MockWrite(
8540 "GET / HTTP/1.1\r\n"
8541 "Host: www.example.org\r\n"
8542 "Connection: keep-alive\r\n"
8543 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168544 };
8545
8546 MockRead data_reads2[] = {
8547 MockRead("HTTP/1.0 200 OK\r\n"),
8548 MockRead("Content-Length: 100\r\n\r\n"),
8549 MockRead(SYNCHRONOUS, OK),
8550 };
8551
Ryan Sleevib8d7ea02018-05-07 20:01:018552 StaticSocketDataProvider data1(data_reads1, data_writes1);
8553 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078554 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8555 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238556
[email protected]49639fa2011-12-20 23:22:418557 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208558 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018559 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238560 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018561 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168562 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168563
8564 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168565 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018566 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168567 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018568 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168569 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228570
bnc691fda62016-08-12 00:43:168571 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528572 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168573
8574 // There is no challenge info, since the identity in URL worked.
Emily Starkf2c9bbd2019-04-09 17:08:588575 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]2262e3a2012-05-22 16:08:168576
8577 EXPECT_EQ(100, response->headers->GetContentLength());
8578
8579 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558580 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:168581}
8582
8583// Test the request-challenge-retry sequence for basic auth when there is an
8584// incorrect identity in the URL. The identity from the URL should be used only
8585// once.
bncd16676a2016-07-20 16:23:018586TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:168587 HttpRequestInfo request;
8588 request.method = "GET";
8589 // Note: the URL has a username:password in it. The password "baz" is
8590 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:238591 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:168592
8593 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:108594 request.traffic_annotation =
8595 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:168596
danakj1fd259a02016-04-16 03:17:098597 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168598 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:168599
8600 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238601 MockWrite(
8602 "GET / HTTP/1.1\r\n"
8603 "Host: www.example.org\r\n"
8604 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168605 };
8606
8607 MockRead data_reads1[] = {
8608 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8609 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8610 MockRead("Content-Length: 10\r\n\r\n"),
8611 MockRead(SYNCHRONOUS, ERR_FAILED),
8612 };
8613
8614 // After the challenge above, the transaction will be restarted using the
8615 // identity from the url (foo, baz) to answer the challenge.
8616 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238617 MockWrite(
8618 "GET / HTTP/1.1\r\n"
8619 "Host: www.example.org\r\n"
8620 "Connection: keep-alive\r\n"
8621 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168622 };
8623
8624 MockRead data_reads2[] = {
8625 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8626 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8627 MockRead("Content-Length: 10\r\n\r\n"),
8628 MockRead(SYNCHRONOUS, ERR_FAILED),
8629 };
8630
8631 // After the challenge above, the transaction will be restarted using the
8632 // identity supplied by the user (foo, bar) to answer the challenge.
8633 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238634 MockWrite(
8635 "GET / HTTP/1.1\r\n"
8636 "Host: www.example.org\r\n"
8637 "Connection: keep-alive\r\n"
8638 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168639 };
8640
8641 MockRead data_reads3[] = {
8642 MockRead("HTTP/1.0 200 OK\r\n"),
8643 MockRead("Content-Length: 100\r\n\r\n"),
8644 MockRead(SYNCHRONOUS, OK),
8645 };
8646
Ryan Sleevib8d7ea02018-05-07 20:01:018647 StaticSocketDataProvider data1(data_reads1, data_writes1);
8648 StaticSocketDataProvider data2(data_reads2, data_writes2);
8649 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:078650 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8651 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8652 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:168653
8654 TestCompletionCallback callback1;
8655
tfarina42834112016-09-22 13:38:208656 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018657 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168658
8659 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018660 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:168661
bnc691fda62016-08-12 00:43:168662 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168663 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168664 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018665 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168666 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018667 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168668 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168669
bnc691fda62016-08-12 00:43:168670 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528671 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:588672 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]2262e3a2012-05-22 16:08:168673
8674 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168675 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018676 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168677 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018678 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168679 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168680
bnc691fda62016-08-12 00:43:168681 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528682 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168683
8684 // There is no challenge info, since the identity worked.
Emily Starkf2c9bbd2019-04-09 17:08:588685 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]2262e3a2012-05-22 16:08:168686
8687 EXPECT_EQ(100, response->headers->GetContentLength());
8688
[email protected]ea9dc9a2009-09-05 00:43:328689 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558690 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:328691}
8692
[email protected]2217aa22013-10-11 03:03:548693
8694// Test the request-challenge-retry sequence for basic auth when there is a
8695// correct identity in the URL, but its use is being suppressed. The identity
8696// from the URL should never be used.
bncd16676a2016-07-20 16:23:018697TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:548698 HttpRequestInfo request;
8699 request.method = "GET";
bncce36dca22015-04-21 22:11:238700 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:548701 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e2018-02-07 07:41:108702 request.traffic_annotation =
8703 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:548704
danakj1fd259a02016-04-16 03:17:098705 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168706 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:548707
8708 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238709 MockWrite(
8710 "GET / HTTP/1.1\r\n"
8711 "Host: www.example.org\r\n"
8712 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548713 };
8714
8715 MockRead data_reads1[] = {
8716 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8717 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8718 MockRead("Content-Length: 10\r\n\r\n"),
8719 MockRead(SYNCHRONOUS, ERR_FAILED),
8720 };
8721
8722 // After the challenge above, the transaction will be restarted using the
8723 // identity supplied by the user, not the one in the URL, to answer the
8724 // challenge.
8725 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238726 MockWrite(
8727 "GET / HTTP/1.1\r\n"
8728 "Host: www.example.org\r\n"
8729 "Connection: keep-alive\r\n"
8730 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548731 };
8732
8733 MockRead data_reads3[] = {
8734 MockRead("HTTP/1.0 200 OK\r\n"),
8735 MockRead("Content-Length: 100\r\n\r\n"),
8736 MockRead(SYNCHRONOUS, OK),
8737 };
8738
Ryan Sleevib8d7ea02018-05-07 20:01:018739 StaticSocketDataProvider data1(data_reads1, data_writes1);
8740 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]2217aa22013-10-11 03:03:548741 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8742 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8743
8744 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208745 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018746 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548747 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018748 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168749 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548750
bnc691fda62016-08-12 00:43:168751 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528752 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:588753 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]2217aa22013-10-11 03:03:548754
8755 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168756 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018757 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548758 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018759 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168760 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548761
bnc691fda62016-08-12 00:43:168762 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528763 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548764
8765 // There is no challenge info, since the identity worked.
Emily Starkf2c9bbd2019-04-09 17:08:588766 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]2217aa22013-10-11 03:03:548767 EXPECT_EQ(100, response->headers->GetContentLength());
8768
8769 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558770 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:548771}
8772
[email protected]f9ee6b52008-11-08 06:46:238773// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:018774TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:098775 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:238776
8777 // Transaction 1: authenticate (foo, bar) on MyRealm1
8778 {
[email protected]1c773ea12009-04-28 19:58:428779 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238780 request.method = "GET";
bncce36dca22015-04-21 22:11:238781 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:108782 request.traffic_annotation =
8783 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238784
bnc691fda62016-08-12 00:43:168785 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278786
[email protected]f9ee6b52008-11-08 06:46:238787 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238788 MockWrite(
8789 "GET /x/y/z HTTP/1.1\r\n"
8790 "Host: www.example.org\r\n"
8791 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238792 };
8793
8794 MockRead data_reads1[] = {
8795 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8796 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8797 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068798 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238799 };
8800
8801 // Resend with authorization (username=foo, password=bar)
8802 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238803 MockWrite(
8804 "GET /x/y/z HTTP/1.1\r\n"
8805 "Host: www.example.org\r\n"
8806 "Connection: keep-alive\r\n"
8807 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238808 };
8809
8810 // Sever accepts the authorization.
8811 MockRead data_reads2[] = {
8812 MockRead("HTTP/1.0 200 OK\r\n"),
8813 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068814 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238815 };
8816
Ryan Sleevib8d7ea02018-05-07 20:01:018817 StaticSocketDataProvider data1(data_reads1, data_writes1);
8818 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078819 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8820 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238821
[email protected]49639fa2011-12-20 23:22:418822 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238823
tfarina42834112016-09-22 13:38:208824 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238826
8827 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018828 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238829
bnc691fda62016-08-12 00:43:168830 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528831 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:588832 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]f9ee6b52008-11-08 06:46:238833
[email protected]49639fa2011-12-20 23:22:418834 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238835
bnc691fda62016-08-12 00:43:168836 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8837 callback2.callback());
robpercival214763f2016-07-01 23:27:018838 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238839
8840 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018841 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238842
bnc691fda62016-08-12 00:43:168843 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528844 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:588845 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]f9ee6b52008-11-08 06:46:238846 EXPECT_EQ(100, response->headers->GetContentLength());
8847 }
8848
8849 // ------------------------------------------------------------------------
8850
8851 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
8852 {
[email protected]1c773ea12009-04-28 19:58:428853 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238854 request.method = "GET";
8855 // Note that Transaction 1 was at /x/y/z, so this is in the same
8856 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:238857 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:108858 request.traffic_annotation =
8859 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238860
bnc691fda62016-08-12 00:43:168861 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278862
[email protected]f9ee6b52008-11-08 06:46:238863 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238864 MockWrite(
8865 "GET /x/y/a/b HTTP/1.1\r\n"
8866 "Host: www.example.org\r\n"
8867 "Connection: keep-alive\r\n"
8868 // Send preemptive authorization for MyRealm1
8869 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238870 };
8871
8872 // The server didn't like the preemptive authorization, and
8873 // challenges us for a different realm (MyRealm2).
8874 MockRead data_reads1[] = {
8875 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8876 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8877 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068878 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238879 };
8880
8881 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8882 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238883 MockWrite(
8884 "GET /x/y/a/b HTTP/1.1\r\n"
8885 "Host: www.example.org\r\n"
8886 "Connection: keep-alive\r\n"
8887 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238888 };
8889
8890 // Sever accepts the authorization.
8891 MockRead data_reads2[] = {
8892 MockRead("HTTP/1.0 200 OK\r\n"),
8893 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068894 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238895 };
8896
Ryan Sleevib8d7ea02018-05-07 20:01:018897 StaticSocketDataProvider data1(data_reads1, data_writes1);
8898 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078899 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8900 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238901
[email protected]49639fa2011-12-20 23:22:418902 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238903
tfarina42834112016-09-22 13:38:208904 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018905 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238906
8907 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018908 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238909
bnc691fda62016-08-12 00:43:168910 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528911 ASSERT_TRUE(response);
8912 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048913 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438914 EXPECT_EQ("http://www.example.org",
8915 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048916 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198917 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238918
[email protected]49639fa2011-12-20 23:22:418919 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238920
bnc691fda62016-08-12 00:43:168921 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8922 callback2.callback());
robpercival214763f2016-07-01 23:27:018923 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238924
8925 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018926 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238927
bnc691fda62016-08-12 00:43:168928 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528929 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:588930 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]f9ee6b52008-11-08 06:46:238931 EXPECT_EQ(100, response->headers->GetContentLength());
8932 }
8933
8934 // ------------------------------------------------------------------------
8935
8936 // Transaction 3: Resend a request in MyRealm's protection space --
8937 // succeed with preemptive authorization.
8938 {
[email protected]1c773ea12009-04-28 19:58:428939 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238940 request.method = "GET";
bncce36dca22015-04-21 22:11:238941 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e2018-02-07 07:41:108942 request.traffic_annotation =
8943 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238944
bnc691fda62016-08-12 00:43:168945 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278946
[email protected]f9ee6b52008-11-08 06:46:238947 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238948 MockWrite(
8949 "GET /x/y/z2 HTTP/1.1\r\n"
8950 "Host: www.example.org\r\n"
8951 "Connection: keep-alive\r\n"
8952 // The authorization for MyRealm1 gets sent preemptively
8953 // (since the url is in the same protection space)
8954 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238955 };
8956
8957 // Sever accepts the preemptive authorization
8958 MockRead data_reads1[] = {
8959 MockRead("HTTP/1.0 200 OK\r\n"),
8960 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068961 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238962 };
8963
Ryan Sleevib8d7ea02018-05-07 20:01:018964 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078965 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238966
[email protected]49639fa2011-12-20 23:22:418967 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238968
tfarina42834112016-09-22 13:38:208969 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018970 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238971
8972 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018973 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238974
bnc691fda62016-08-12 00:43:168975 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528976 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238977
Emily Starkf2c9bbd2019-04-09 17:08:588978 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]f9ee6b52008-11-08 06:46:238979 EXPECT_EQ(100, response->headers->GetContentLength());
8980 }
8981
8982 // ------------------------------------------------------------------------
8983
8984 // Transaction 4: request another URL in MyRealm (however the
8985 // url is not known to belong to the protection space, so no pre-auth).
8986 {
[email protected]1c773ea12009-04-28 19:58:428987 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238988 request.method = "GET";
bncce36dca22015-04-21 22:11:238989 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e2018-02-07 07:41:108990 request.traffic_annotation =
8991 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238992
bnc691fda62016-08-12 00:43:168993 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278994
[email protected]f9ee6b52008-11-08 06:46:238995 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238996 MockWrite(
8997 "GET /x/1 HTTP/1.1\r\n"
8998 "Host: www.example.org\r\n"
8999 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239000 };
9001
9002 MockRead data_reads1[] = {
9003 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9004 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9005 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069006 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239007 };
9008
9009 // Resend with authorization from MyRealm's cache.
9010 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239011 MockWrite(
9012 "GET /x/1 HTTP/1.1\r\n"
9013 "Host: www.example.org\r\n"
9014 "Connection: keep-alive\r\n"
9015 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239016 };
9017
9018 // Sever accepts the authorization.
9019 MockRead data_reads2[] = {
9020 MockRead("HTTP/1.0 200 OK\r\n"),
9021 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069022 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239023 };
9024
Ryan Sleevib8d7ea02018-05-07 20:01:019025 StaticSocketDataProvider data1(data_reads1, data_writes1);
9026 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079027 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9028 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:239029
[email protected]49639fa2011-12-20 23:22:419030 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239031
tfarina42834112016-09-22 13:38:209032 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019033 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239034
9035 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019036 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239037
bnc691fda62016-08-12 00:43:169038 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419039 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169040 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019041 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229042 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019043 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169044 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229045
bnc691fda62016-08-12 00:43:169046 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529047 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589048 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]f9ee6b52008-11-08 06:46:239049 EXPECT_EQ(100, response->headers->GetContentLength());
9050 }
9051
9052 // ------------------------------------------------------------------------
9053
9054 // Transaction 5: request a URL in MyRealm, but the server rejects the
9055 // cached identity. Should invalidate and re-prompt.
9056 {
[email protected]1c773ea12009-04-28 19:58:429057 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:239058 request.method = "GET";
bncce36dca22015-04-21 22:11:239059 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e2018-02-07 07:41:109060 request.traffic_annotation =
9061 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:239062
bnc691fda62016-08-12 00:43:169063 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279064
[email protected]f9ee6b52008-11-08 06:46:239065 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239066 MockWrite(
9067 "GET /p/q/t HTTP/1.1\r\n"
9068 "Host: www.example.org\r\n"
9069 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239070 };
9071
9072 MockRead data_reads1[] = {
9073 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9074 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9075 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069076 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239077 };
9078
9079 // Resend with authorization from cache for MyRealm.
9080 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239081 MockWrite(
9082 "GET /p/q/t HTTP/1.1\r\n"
9083 "Host: www.example.org\r\n"
9084 "Connection: keep-alive\r\n"
9085 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239086 };
9087
9088 // Sever rejects the authorization.
9089 MockRead data_reads2[] = {
9090 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9091 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9092 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069093 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239094 };
9095
9096 // At this point we should prompt for new credentials for MyRealm.
9097 // Restart with username=foo3, password=foo4.
9098 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239099 MockWrite(
9100 "GET /p/q/t HTTP/1.1\r\n"
9101 "Host: www.example.org\r\n"
9102 "Connection: keep-alive\r\n"
9103 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239104 };
9105
9106 // Sever accepts the authorization.
9107 MockRead data_reads3[] = {
9108 MockRead("HTTP/1.0 200 OK\r\n"),
9109 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069110 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239111 };
9112
Ryan Sleevib8d7ea02018-05-07 20:01:019113 StaticSocketDataProvider data1(data_reads1, data_writes1);
9114 StaticSocketDataProvider data2(data_reads2, data_writes2);
9115 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:079116 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9117 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9118 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:239119
[email protected]49639fa2011-12-20 23:22:419120 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239121
tfarina42834112016-09-22 13:38:209122 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019123 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239124
9125 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019126 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239127
bnc691fda62016-08-12 00:43:169128 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419129 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169130 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019131 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229132 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019133 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169134 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229135
bnc691fda62016-08-12 00:43:169136 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529137 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589138 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]f9ee6b52008-11-08 06:46:239139
[email protected]49639fa2011-12-20 23:22:419140 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:239141
bnc691fda62016-08-12 00:43:169142 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
9143 callback3.callback());
robpercival214763f2016-07-01 23:27:019144 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239145
[email protected]0757e7702009-03-27 04:00:229146 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:019147 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239148
bnc691fda62016-08-12 00:43:169149 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529150 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589151 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]f9ee6b52008-11-08 06:46:239152 EXPECT_EQ(100, response->headers->GetContentLength());
9153 }
9154}
[email protected]89ceba9a2009-03-21 03:46:069155
[email protected]3c32c5f2010-05-18 15:18:129156// Tests that nonce count increments when multiple auth attempts
9157// are started with the same nonce.
bncd16676a2016-07-20 16:23:019158TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:449159 HttpAuthHandlerDigest::Factory* digest_factory =
9160 new HttpAuthHandlerDigest::Factory();
9161 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
9162 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
9163 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:079164 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:099165 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:129166
9167 // Transaction 1: authenticate (foo, bar) on MyRealm1
9168 {
[email protected]3c32c5f2010-05-18 15:18:129169 HttpRequestInfo request;
9170 request.method = "GET";
bncce36dca22015-04-21 22:11:239171 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:109172 request.traffic_annotation =
9173 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129174
bnc691fda62016-08-12 00:43:169175 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279176
[email protected]3c32c5f2010-05-18 15:18:129177 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239178 MockWrite(
9179 "GET /x/y/z HTTP/1.1\r\n"
9180 "Host: www.example.org\r\n"
9181 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129182 };
9183
9184 MockRead data_reads1[] = {
9185 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9186 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
9187 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069188 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129189 };
9190
9191 // Resend with authorization (username=foo, password=bar)
9192 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239193 MockWrite(
9194 "GET /x/y/z HTTP/1.1\r\n"
9195 "Host: www.example.org\r\n"
9196 "Connection: keep-alive\r\n"
9197 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9198 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
9199 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
9200 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129201 };
9202
9203 // Sever accepts the authorization.
9204 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:089205 MockRead("HTTP/1.0 200 OK\r\n"),
9206 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129207 };
9208
Ryan Sleevib8d7ea02018-05-07 20:01:019209 StaticSocketDataProvider data1(data_reads1, data_writes1);
9210 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079211 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9212 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:129213
[email protected]49639fa2011-12-20 23:22:419214 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129215
tfarina42834112016-09-22 13:38:209216 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019217 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129218
9219 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019220 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129221
bnc691fda62016-08-12 00:43:169222 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529223 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589224 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge));
[email protected]3c32c5f2010-05-18 15:18:129225
[email protected]49639fa2011-12-20 23:22:419226 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:129227
bnc691fda62016-08-12 00:43:169228 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
9229 callback2.callback());
robpercival214763f2016-07-01 23:27:019230 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129231
9232 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019233 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129234
bnc691fda62016-08-12 00:43:169235 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529236 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589237 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]3c32c5f2010-05-18 15:18:129238 }
9239
9240 // ------------------------------------------------------------------------
9241
9242 // Transaction 2: Request another resource in digestive's protection space.
9243 // This will preemptively add an Authorization header which should have an
9244 // "nc" value of 2 (as compared to 1 in the first use.
9245 {
[email protected]3c32c5f2010-05-18 15:18:129246 HttpRequestInfo request;
9247 request.method = "GET";
9248 // Note that Transaction 1 was at /x/y/z, so this is in the same
9249 // protection space as digest.
bncce36dca22015-04-21 22:11:239250 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:109251 request.traffic_annotation =
9252 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129253
bnc691fda62016-08-12 00:43:169254 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279255
[email protected]3c32c5f2010-05-18 15:18:129256 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239257 MockWrite(
9258 "GET /x/y/a/b HTTP/1.1\r\n"
9259 "Host: www.example.org\r\n"
9260 "Connection: keep-alive\r\n"
9261 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9262 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
9263 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
9264 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129265 };
9266
9267 // Sever accepts the authorization.
9268 MockRead data_reads1[] = {
9269 MockRead("HTTP/1.0 200 OK\r\n"),
9270 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069271 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129272 };
9273
Ryan Sleevib8d7ea02018-05-07 20:01:019274 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:079275 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:129276
[email protected]49639fa2011-12-20 23:22:419277 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129278
tfarina42834112016-09-22 13:38:209279 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019280 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129281
9282 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019283 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129284
bnc691fda62016-08-12 00:43:169285 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529286 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589287 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]3c32c5f2010-05-18 15:18:129288 }
9289}
9290
[email protected]89ceba9a2009-03-21 03:46:069291// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:019292TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:069293 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:099294 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169295 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:069296
9297 // Setup some state (which we expect ResetStateForRestart() will clear).
Victor Costan9c7302b2018-08-27 16:39:449298 trans.read_buf_ = base::MakeRefCounted<IOBuffer>(15);
bnc691fda62016-08-12 00:43:169299 trans.read_buf_len_ = 15;
9300 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:069301
9302 // Setup state in response_
bnc691fda62016-08-12 00:43:169303 HttpResponseInfo* response = &trans.response_;
Emily Starkf2c9bbd2019-04-09 17:08:589304 response->auth_challenge = base::nullopt;
[email protected]70d66502011-09-23 00:55:089305 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:579306 response->response_time = base::Time::Now();
9307 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:069308
9309 { // Setup state for response_.vary_data
9310 HttpRequestInfo request;
9311 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
9312 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:279313 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:439314 request.extra_headers.SetHeader("Foo", "1");
9315 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:509316 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:069317 }
9318
9319 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:169320 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:069321
9322 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:169323 EXPECT_FALSE(trans.read_buf_);
9324 EXPECT_EQ(0, trans.read_buf_len_);
9325 EXPECT_TRUE(trans.request_headers_.IsEmpty());
Emily Starkf2c9bbd2019-04-09 17:08:589326 EXPECT_FALSE(response->auth_challenge.has_value());
wezca1070932016-05-26 20:30:529327 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:049328 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:089329 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:579330 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:069331}
9332
[email protected]bacff652009-03-31 17:50:339333// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:019334TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:339335 HttpRequestInfo request;
9336 request.method = "GET";
bncce36dca22015-04-21 22:11:239337 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109338 request.traffic_annotation =
9339 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339340
danakj1fd259a02016-04-16 03:17:099341 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169342 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279343
[email protected]bacff652009-03-31 17:50:339344 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239345 MockWrite(
9346 "GET / HTTP/1.1\r\n"
9347 "Host: www.example.org\r\n"
9348 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339349 };
9350
9351 MockRead data_reads[] = {
9352 MockRead("HTTP/1.0 200 OK\r\n"),
9353 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9354 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069355 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339356 };
9357
[email protected]5ecc992a42009-11-11 01:41:599358 StaticSocketDataProvider ssl_bad_certificate;
Ryan Sleevib8d7ea02018-05-07 20:01:019359 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069360 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9361 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339362
[email protected]bb88e1d32013-05-03 23:11:079363 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9364 session_deps_.socket_factory->AddSocketDataProvider(&data);
9365 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9366 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339367
[email protected]49639fa2011-12-20 23:22:419368 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339369
tfarina42834112016-09-22 13:38:209370 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019371 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339372
9373 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019374 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339375
bnc691fda62016-08-12 00:43:169376 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019377 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339378
9379 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019380 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339381
bnc691fda62016-08-12 00:43:169382 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339383
wezca1070932016-05-26 20:30:529384 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339385 EXPECT_EQ(100, response->headers->GetContentLength());
9386}
9387
9388// Test HTTPS connections to a site with a bad certificate, going through a
9389// proxy
bncd16676a2016-07-20 16:23:019390TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499391 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9392 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339393
9394 HttpRequestInfo request;
9395 request.method = "GET";
bncce36dca22015-04-21 22:11:239396 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109397 request.traffic_annotation =
9398 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339399
9400 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:179401 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9402 "Host: www.example.org:443\r\n"
9403 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339404 };
9405
9406 MockRead proxy_reads[] = {
9407 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069408 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:339409 };
9410
9411 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179412 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9413 "Host: www.example.org:443\r\n"
9414 "Proxy-Connection: keep-alive\r\n\r\n"),
9415 MockWrite("GET / HTTP/1.1\r\n"
9416 "Host: www.example.org\r\n"
9417 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339418 };
9419
9420 MockRead data_reads[] = {
9421 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9422 MockRead("HTTP/1.0 200 OK\r\n"),
9423 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9424 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069425 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339426 };
9427
Ryan Sleevib8d7ea02018-05-07 20:01:019428 StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
9429 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069430 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9431 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339432
[email protected]bb88e1d32013-05-03 23:11:079433 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9434 session_deps_.socket_factory->AddSocketDataProvider(&data);
9435 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9436 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339437
[email protected]49639fa2011-12-20 23:22:419438 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339439
9440 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:079441 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:339442
danakj1fd259a02016-04-16 03:17:099443 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169444 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:339445
tfarina42834112016-09-22 13:38:209446 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019447 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339448
9449 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019450 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339451
bnc691fda62016-08-12 00:43:169452 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019453 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339454
9455 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019456 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339457
bnc691fda62016-08-12 00:43:169458 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339459
wezca1070932016-05-26 20:30:529460 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339461 EXPECT_EQ(100, response->headers->GetContentLength());
9462 }
9463}
9464
[email protected]2df19bb2010-08-25 20:13:469465
9466// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:019467TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599468 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499469 ProxyResolutionService::CreateFixedFromPacResult(
9470 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519471 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079472 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:469473
9474 HttpRequestInfo request;
9475 request.method = "GET";
bncce36dca22015-04-21 22:11:239476 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109477 request.traffic_annotation =
9478 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469479
9480 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179481 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9482 "Host: www.example.org:443\r\n"
9483 "Proxy-Connection: keep-alive\r\n\r\n"),
9484 MockWrite("GET / HTTP/1.1\r\n"
9485 "Host: www.example.org\r\n"
9486 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469487 };
9488
9489 MockRead data_reads[] = {
9490 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9491 MockRead("HTTP/1.1 200 OK\r\n"),
9492 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9493 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069494 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469495 };
9496
Ryan Sleevib8d7ea02018-05-07 20:01:019497 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069498 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9499 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:469500
[email protected]bb88e1d32013-05-03 23:11:079501 session_deps_.socket_factory->AddSocketDataProvider(&data);
9502 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9503 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:469504
[email protected]49639fa2011-12-20 23:22:419505 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469506
danakj1fd259a02016-04-16 03:17:099507 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169508 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469509
tfarina42834112016-09-22 13:38:209510 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019511 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469512
9513 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019514 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169515 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469516
wezca1070932016-05-26 20:30:529517 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469518
tbansal2ecbbc72016-10-06 17:15:479519 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:469520 EXPECT_TRUE(response->headers->IsKeepAlive());
9521 EXPECT_EQ(200, response->headers->response_code());
9522 EXPECT_EQ(100, response->headers->GetContentLength());
9523 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209524
9525 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169526 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209527 TestLoadTimingNotReusedWithPac(load_timing_info,
9528 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:469529}
9530
Eric Roman695a7872019-04-16 21:53:299531// Test that an HTTPS Proxy cannot redirect a CONNECT request for main frames.
bncd16676a2016-07-20 16:23:019532TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599533 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499534 ProxyResolutionService::CreateFixedFromPacResult(
9535 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519536 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079537 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:299538
Matt Menkeecfecfc72019-02-05 19:15:289539 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9540 session_deps_.host_resolver->set_ondemand_mode(true);
9541
[email protected]511f6f52010-12-17 03:58:299542 HttpRequestInfo request;
Eric Roman74103c72019-02-21 00:23:129543 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
[email protected]511f6f52010-12-17 03:58:299544 request.method = "GET";
bncce36dca22015-04-21 22:11:239545 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109546 request.traffic_annotation =
9547 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299548
9549 MockWrite data_writes[] = {
Matt Menkeecfecfc72019-02-05 19:15:289550 MockWrite(ASYNC, 0,
9551 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:179552 "Host: www.example.org:443\r\n"
9553 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299554 };
9555
9556 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289557 // Pause on first read.
9558 MockRead(ASYNC, ERR_IO_PENDING, 1),
9559 MockRead(ASYNC, 2, "HTTP/1.1 302 Redirect\r\n"),
9560 MockRead(ASYNC, 3, "Location: http://login.example.com/\r\n"),
9561 MockRead(ASYNC, 4, "Content-Length: 0\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299562 };
9563
Matt Menkeecfecfc72019-02-05 19:15:289564 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069565 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299566
[email protected]bb88e1d32013-05-03 23:11:079567 session_deps_.socket_factory->AddSocketDataProvider(&data);
9568 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299569
[email protected]49639fa2011-12-20 23:22:419570 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299571
danakj1fd259a02016-04-16 03:17:099572 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169573 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299574
tfarina42834112016-09-22 13:38:209575 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019576 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289577 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
9578
9579 // Host resolution takes |kTimeIncrement|.
9580 FastForwardBy(kTimeIncrement);
9581 // Resolving the current request with |ResolveNow| will cause the pending
9582 // request to instantly complete, and the async connect will start as well.
9583 session_deps_.host_resolver->ResolveOnlyRequestNow();
9584
9585 // Connecting takes |kTimeIncrement|.
9586 FastForwardBy(kTimeIncrement);
9587 data.RunUntilPaused();
9588
9589 // The server takes |kTimeIncrement| to respond.
9590 FastForwardBy(kTimeIncrement);
9591 data.Resume();
[email protected]511f6f52010-12-17 03:58:299592
9593 rv = callback.WaitForResult();
Eric Roman695a7872019-04-16 21:53:299594 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
[email protected]511f6f52010-12-17 03:58:299595}
9596
Eric Roman74103c72019-02-21 00:23:129597// Test that an HTTPS Proxy cannot redirect a CONNECT request for subresources.
9598TEST_F(HttpNetworkTransactionTest,
9599 RedirectOfHttpsConnectSubresourceViaHttpsProxy) {
9600 base::HistogramTester histograms;
9601 session_deps_.proxy_resolution_service =
9602 ProxyResolutionService::CreateFixedFromPacResult(
9603 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9604 TestNetLog net_log;
9605 session_deps_.net_log = &net_log;
9606
9607 HttpRequestInfo request;
9608 request.method = "GET";
9609 request.url = GURL("https://www.example.org/");
9610 request.traffic_annotation =
9611 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9612
9613 MockWrite data_writes[] = {
9614 MockWrite(ASYNC, 0,
9615 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9616 "Host: www.example.org:443\r\n"
9617 "Proxy-Connection: keep-alive\r\n\r\n"),
9618 };
9619
9620 MockRead data_reads[] = {
9621 MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
9622 MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
9623 MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
9624 };
9625
9626 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
9627 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9628
9629 session_deps_.socket_factory->AddSocketDataProvider(&data);
9630 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9631
9632 TestCompletionCallback callback;
9633
9634 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9635 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9636
9637 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9638 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9639
9640 rv = callback.WaitForResult();
9641 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
9642
9643 histograms.ExpectUniqueSample(
9644 "Net.Proxy.RedirectDuringConnect",
9645 HttpNetworkTransaction::kSubresourceByExplicitProxy, 1);
9646}
9647
9648// Test that an HTTPS Proxy which was auto-detected cannot redirect a CONNECT
9649// request for main frames.
9650TEST_F(HttpNetworkTransactionTest,
9651 RedirectOfHttpsConnectViaAutoDetectedHttpsProxy) {
9652 base::HistogramTester histograms;
9653 session_deps_.proxy_resolution_service =
9654 ProxyResolutionService::CreateFixedFromAutoDetectedPacResult(
9655 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9656 TestNetLog net_log;
9657 session_deps_.net_log = &net_log;
9658
9659 HttpRequestInfo request;
9660 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
9661 request.method = "GET";
9662 request.url = GURL("https://www.example.org/");
9663 request.traffic_annotation =
9664 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9665
9666 MockWrite data_writes[] = {
9667 MockWrite(ASYNC, 0,
9668 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9669 "Host: www.example.org:443\r\n"
9670 "Proxy-Connection: keep-alive\r\n\r\n"),
9671 };
9672
9673 MockRead data_reads[] = {
9674 MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
9675 MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
9676 MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
9677 };
9678
9679 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
9680 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9681
9682 session_deps_.socket_factory->AddSocketDataProvider(&data);
9683 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9684
9685 TestCompletionCallback callback;
9686
9687 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9688 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9689
9690 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9691 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9692
9693 rv = callback.WaitForResult();
9694 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
9695
9696 histograms.ExpectUniqueSample(
9697 "Net.Proxy.RedirectDuringConnect",
9698 HttpNetworkTransaction::kMainFrameByAutoDetectedProxy, 1);
9699}
9700
Eric Roman695a7872019-04-16 21:53:299701// Tests that an HTTPS (SPDY) Proxy's cannot redirect a CONNECT request for main
Eric Roman74103c72019-02-21 00:23:129702// frames.
bncd16676a2016-07-20 16:23:019703TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Eric Roman74103c72019-02-21 00:23:129704 base::HistogramTester histograms;
Ramin Halavatica8d5252018-03-12 05:33:499705 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9706 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeecfecfc72019-02-05 19:15:289707 TestNetLog net_log;
9708 session_deps_.net_log = &net_log;
9709
Matt Menkeecfecfc72019-02-05 19:15:289710 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9711 session_deps_.host_resolver->set_ondemand_mode(true);
[email protected]511f6f52010-12-17 03:58:299712
9713 HttpRequestInfo request;
9714 request.method = "GET";
Eric Roman74103c72019-02-21 00:23:129715 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
bncce36dca22015-04-21 22:11:239716 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109717 request.traffic_annotation =
9718 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299719
Ryan Hamilton0239aac2018-05-19 00:03:139720 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049721 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9722 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139723 spdy::SpdySerializedFrame goaway(
9724 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299725 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419726 CreateMockWrite(conn, 0, SYNCHRONOUS),
Matt Menkeecfecfc72019-02-05 19:15:289727 CreateMockWrite(goaway, 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:299728 };
9729
9730 static const char* const kExtraHeaders[] = {
9731 "location",
9732 "http://login.example.com/",
9733 };
Ryan Hamilton0239aac2018-05-19 00:03:139734 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249735 "302", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:299736 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289737 // Pause on first read.
9738 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2),
9739 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299740 };
9741
Matt Menkeecfecfc72019-02-05 19:15:289742 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069743 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369744 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299745
[email protected]bb88e1d32013-05-03 23:11:079746 session_deps_.socket_factory->AddSocketDataProvider(&data);
9747 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299748
[email protected]49639fa2011-12-20 23:22:419749 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299750
danakj1fd259a02016-04-16 03:17:099751 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169752 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299753
tfarina42834112016-09-22 13:38:209754 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019755 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289756 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
[email protected]511f6f52010-12-17 03:58:299757
Matt Menkeecfecfc72019-02-05 19:15:289758 // Host resolution takes |kTimeIncrement|.
9759 FastForwardBy(kTimeIncrement);
9760 // Resolving the current request with |ResolveNow| will cause the pending
9761 // request to instantly complete, and the async connect will start as well.
9762 session_deps_.host_resolver->ResolveOnlyRequestNow();
9763
9764 // Connecting takes |kTimeIncrement|.
9765 FastForwardBy(kTimeIncrement);
9766 data.RunUntilPaused();
9767
9768 FastForwardBy(kTimeIncrement);
9769 data.Resume();
[email protected]511f6f52010-12-17 03:58:299770 rv = callback.WaitForResult();
Eric Roman695a7872019-04-16 21:53:299771 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
Eric Roman74103c72019-02-21 00:23:129772
9773 histograms.ExpectUniqueSample(
9774 "Net.Proxy.RedirectDuringConnect",
9775 HttpNetworkTransaction::kMainFrameByExplicitProxy, 1);
[email protected]511f6f52010-12-17 03:58:299776}
9777
[email protected]4eddbc732012-08-09 05:40:179778// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019779TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499780 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9781 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299782
9783 HttpRequestInfo request;
9784 request.method = "GET";
bncce36dca22015-04-21 22:11:239785 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109786 request.traffic_annotation =
9787 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299788
9789 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179790 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9791 "Host: www.example.org:443\r\n"
9792 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299793 };
9794
9795 MockRead data_reads[] = {
9796 MockRead("HTTP/1.1 404 Not Found\r\n"),
9797 MockRead("Content-Length: 23\r\n\r\n"),
9798 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:069799 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:299800 };
9801
Ryan Sleevib8d7ea02018-05-07 20:01:019802 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069803 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299804
[email protected]bb88e1d32013-05-03 23:11:079805 session_deps_.socket_factory->AddSocketDataProvider(&data);
9806 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299807
[email protected]49639fa2011-12-20 23:22:419808 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299809
danakj1fd259a02016-04-16 03:17:099810 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169811 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299812
tfarina42834112016-09-22 13:38:209813 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299815
9816 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019817 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299818
ttuttle960fcbf2016-04-19 13:26:329819 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299820}
9821
[email protected]4eddbc732012-08-09 05:40:179822// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019823TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499824 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9825 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299826
9827 HttpRequestInfo request;
9828 request.method = "GET";
bncce36dca22015-04-21 22:11:239829 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109830 request.traffic_annotation =
9831 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299832
Ryan Hamilton0239aac2018-05-19 00:03:139833 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049834 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9835 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139836 spdy::SpdySerializedFrame rst(
9837 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299838 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419839 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:299840 };
9841
9842 static const char* const kExtraHeaders[] = {
9843 "location",
9844 "http://login.example.com/",
9845 };
Ryan Hamilton0239aac2018-05-19 00:03:139846 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249847 "404", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:139848 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:199849 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:299850 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:419851 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:139852 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299853 };
9854
Ryan Sleevib8d7ea02018-05-07 20:01:019855 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069856 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369857 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299858
[email protected]bb88e1d32013-05-03 23:11:079859 session_deps_.socket_factory->AddSocketDataProvider(&data);
9860 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299861
[email protected]49639fa2011-12-20 23:22:419862 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299863
danakj1fd259a02016-04-16 03:17:099864 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169865 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299866
tfarina42834112016-09-22 13:38:209867 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019868 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299869
9870 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019871 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299872
ttuttle960fcbf2016-04-19 13:26:329873 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299874}
9875
[email protected]0c5fb722012-02-28 11:50:359876// Test the request-challenge-retry sequence for basic auth, through
9877// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:019878TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:359879 HttpRequestInfo request;
9880 request.method = "GET";
bncce36dca22015-04-21 22:11:239881 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:359882 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:299883 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:109884 request.traffic_annotation =
9885 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:359886
9887 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599888 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499889 ProxyResolutionService::CreateFixedFromPacResult(
9890 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519891 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079892 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:099893 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:359894
9895 // Since we have proxy, should try to establish tunnel.
Ryan Hamilton0239aac2018-05-19 00:03:139896 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049897 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9898 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139899 spdy::SpdySerializedFrame rst(
9900 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:389901 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:359902
bnc691fda62016-08-12 00:43:169903 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:359904 // be issuing -- the final header line contains the credentials.
9905 const char* const kAuthCredentials[] = {
9906 "proxy-authorization", "Basic Zm9vOmJhcg==",
9907 };
Ryan Hamilton0239aac2018-05-19 00:03:139908 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049909 kAuthCredentials, base::size(kAuthCredentials) / 2, 3,
9910 HttpProxyConnectJob::kH2QuicTunnelPriority,
bncce36dca22015-04-21 22:11:239911 HostPortPair("www.example.org", 443)));
9912 // fetch https://www.example.org/ via HTTP
9913 const char get[] =
9914 "GET / HTTP/1.1\r\n"
9915 "Host: www.example.org\r\n"
9916 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:139917 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:199918 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:359919
9920 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419921 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
9922 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:359923 };
9924
9925 // The proxy responds to the connect with a 407, using a persistent
9926 // connection.
thestig9d3bb0c2015-01-24 00:49:519927 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:359928 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:359929 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
9930 };
Ryan Hamilton0239aac2018-05-19 00:03:139931 spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249932 kAuthStatus, kAuthChallenge, base::size(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:359933
Ryan Hamilton0239aac2018-05-19 00:03:139934 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:359935 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
[email protected]0c5fb722012-02-28 11:50:359936 const char resp[] = "HTTP/1.1 200 OK\r\n"
9937 "Content-Length: 5\r\n\r\n";
9938
Ryan Hamilton0239aac2018-05-19 00:03:139939 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:199940 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:139941 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:199942 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:359943 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419944 CreateMockRead(conn_auth_resp, 1, ASYNC),
9945 CreateMockRead(conn_resp, 4, ASYNC),
9946 CreateMockRead(wrapped_get_resp, 6, ASYNC),
9947 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:139948 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:359949 };
9950
Ryan Sleevib8d7ea02018-05-07 20:01:019951 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079952 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:359953 // Negotiate SPDY to the proxy
9954 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369955 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079956 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:359957 // Vanilla SSL to the server
9958 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079959 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:359960
9961 TestCompletionCallback callback1;
9962
bnc87dcefc2017-05-25 12:47:589963 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199964 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:359965
9966 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019967 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359968
9969 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019970 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:469971 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:359972 log.GetEntries(&entries);
9973 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:009974 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
9975 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359976 ExpectLogContainsSomewhere(
9977 entries, pos,
mikecirone8b85c432016-09-08 19:11:009978 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9979 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359980
9981 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529982 ASSERT_TRUE(response);
9983 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:359984 EXPECT_EQ(407, response->headers->response_code());
9985 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:589986 EXPECT_TRUE(response->auth_challenge.has_value());
9987 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
[email protected]0c5fb722012-02-28 11:50:359988
9989 TestCompletionCallback callback2;
9990
9991 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
9992 callback2.callback());
robpercival214763f2016-07-01 23:27:019993 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359994
9995 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019996 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:359997
9998 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529999 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:3510000
10001 EXPECT_TRUE(response->headers->IsKeepAlive());
10002 EXPECT_EQ(200, response->headers->response_code());
10003 EXPECT_EQ(5, response->headers->GetContentLength());
10004 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10005
10006 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:5810007 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0c5fb722012-02-28 11:50:3510008
[email protected]029c83b62013-01-24 05:28:2010009 LoadTimingInfo load_timing_info;
10010 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10011 TestLoadTimingNotReusedWithPac(load_timing_info,
10012 CONNECT_TIMING_HAS_SSL_TIMES);
10013
[email protected]0c5fb722012-02-28 11:50:3510014 trans.reset();
10015 session->CloseAllConnections();
10016}
10017
[email protected]7c6f7ba2012-04-03 04:09:2910018// Test that an explicitly trusted SPDY proxy can push a resource from an
10019// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:0110020TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:1510021 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910022 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510023 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10024 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:2910025 HttpRequestInfo request;
10026 HttpRequestInfo push_request;
Ramin Halavatib5e433e2018-02-07 07:41:1010027 request.traffic_annotation =
10028 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:2910029
[email protected]7c6f7ba2012-04-03 04:09:2910030 request.method = "GET";
bncce36dca22015-04-21 22:11:2310031 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:2910032 push_request.method = "GET";
10033 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e2018-02-07 07:41:1010034 push_request.traffic_annotation =
10035 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:2910036
tbansal28e68f82016-02-04 02:56:1510037 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:5910038 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910039 ProxyResolutionService::CreateFixedFromPacResult(
10040 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110041 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710042 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010043
Eric Roman3d8546a2018-09-10 17:00:5210044 session_deps_.proxy_resolution_service->SetProxyDelegate(
10045 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010046
danakj1fd259a02016-04-16 03:17:0910047 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:2910048
Ryan Hamilton0239aac2018-05-19 00:03:1310049 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510050 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310051 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510052 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:2910053
10054 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110055 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510056 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:2910057 };
10058
Ryan Hamilton0239aac2018-05-19 00:03:1310059 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Raul Tambre94493c652019-03-11 17:18:3510060 nullptr, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
Bence Béky7bf94362018-01-10 13:19:3610061
Ryan Hamilton0239aac2018-05-19 00:03:1310062 spdy::SpdySerializedFrame stream1_reply(
Raul Tambre94493c652019-03-11 17:18:3510063 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:2910064
Ryan Hamilton0239aac2018-05-19 00:03:1310065 spdy::SpdySerializedFrame stream1_body(
10066 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:2910067
Ryan Hamilton0239aac2018-05-19 00:03:1310068 spdy::SpdySerializedFrame stream2_body(
Bence Békyd74f4382018-02-20 18:26:1910069 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:2910070
10071 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:3610072 CreateMockRead(stream2_syn, 1, ASYNC),
10073 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510074 CreateMockRead(stream1_body, 4, ASYNC),
10075 CreateMockRead(stream2_body, 5, ASYNC),
10076 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:2910077 };
10078
Ryan Sleevib8d7ea02018-05-07 20:01:0110079 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710080 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:2910081 // Negotiate SPDY to the proxy
10082 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610083 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710084 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:2910085
bnc87dcefc2017-05-25 12:47:5810086 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910087 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:2910088 TestCompletionCallback callback;
10089 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910091
10092 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110093 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910094 const HttpResponseInfo* response = trans->GetResponseInfo();
10095
bnc87dcefc2017-05-25 12:47:5810096 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:1910097 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:5010098 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110099 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910100
10101 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110102 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910103 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
10104
wezca1070932016-05-26 20:30:5210105 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:2910106 EXPECT_TRUE(response->headers->IsKeepAlive());
10107
10108 EXPECT_EQ(200, response->headers->response_code());
10109 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10110
10111 std::string response_data;
10112 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110113 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910114 EXPECT_EQ("hello!", response_data);
10115
[email protected]029c83b62013-01-24 05:28:2010116 LoadTimingInfo load_timing_info;
10117 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10118 TestLoadTimingNotReusedWithPac(load_timing_info,
10119 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10120
[email protected]7c6f7ba2012-04-03 04:09:2910121 // Verify the pushed stream.
wezca1070932016-05-26 20:30:5210122 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:2910123 EXPECT_EQ(200, push_response->headers->response_code());
10124
10125 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110126 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910127 EXPECT_EQ("pushed", response_data);
10128
[email protected]029c83b62013-01-24 05:28:2010129 LoadTimingInfo push_load_timing_info;
10130 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
10131 TestLoadTimingReusedWithPac(push_load_timing_info);
10132 // The transactions should share a socket ID, despite being for different
10133 // origins.
10134 EXPECT_EQ(load_timing_info.socket_log_id,
10135 push_load_timing_info.socket_log_id);
10136
[email protected]7c6f7ba2012-04-03 04:09:2910137 trans.reset();
10138 push_trans.reset();
10139 session->CloseAllConnections();
10140}
10141
[email protected]8c843192012-04-05 07:15:0010142// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:0110143TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510144 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910145 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510146 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10147 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:0010148 HttpRequestInfo request;
10149
10150 request.method = "GET";
bncce36dca22015-04-21 22:11:2310151 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010152 request.traffic_annotation =
10153 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:0010154
Ramin Halavatica8d5252018-03-12 05:33:4910155 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10156 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110157 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710158 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010159
10160 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210161 session_deps_.proxy_resolution_service->SetProxyDelegate(
10162 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010163
danakj1fd259a02016-04-16 03:17:0910164 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:0010165
Ryan Hamilton0239aac2018-05-19 00:03:1310166 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510167 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:0010168
Ryan Hamilton0239aac2018-05-19 00:03:1310169 spdy::SpdySerializedFrame push_rst(
10170 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:0010171
10172 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110173 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:0010174 };
10175
Ryan Hamilton0239aac2018-05-19 00:03:1310176 spdy::SpdySerializedFrame stream1_reply(
Raul Tambre94493c652019-03-11 17:18:3510177 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]8c843192012-04-05 07:15:0010178
Ryan Hamilton0239aac2018-05-19 00:03:1310179 spdy::SpdySerializedFrame stream1_body(
10180 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:0010181
Ryan Hamilton0239aac2018-05-19 00:03:1310182 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Raul Tambre94493c652019-03-11 17:18:3510183 nullptr, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:0010184
10185 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110186 CreateMockRead(stream1_reply, 1, ASYNC),
10187 CreateMockRead(stream2_syn, 2, ASYNC),
10188 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:5910189 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:0010190 };
10191
Ryan Sleevib8d7ea02018-05-07 20:01:0110192 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710193 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:0010194 // Negotiate SPDY to the proxy
10195 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610196 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710197 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:0010198
bnc87dcefc2017-05-25 12:47:5810199 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910200 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:0010201 TestCompletionCallback callback;
10202 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110203 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:0010204
10205 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110206 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010207 const HttpResponseInfo* response = trans->GetResponseInfo();
10208
wezca1070932016-05-26 20:30:5210209 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:0010210 EXPECT_TRUE(response->headers->IsKeepAlive());
10211
10212 EXPECT_EQ(200, response->headers->response_code());
10213 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10214
10215 std::string response_data;
10216 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110217 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010218 EXPECT_EQ("hello!", response_data);
10219
10220 trans.reset();
10221 session->CloseAllConnections();
10222}
10223
tbansal8ef1d3e2016-02-03 04:05:4210224// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
10225// resources.
bncd16676a2016-07-20 16:23:0110226TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510227 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910228 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510229 proxy_delegate->set_trusted_spdy_proxy(
10230 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
10231
tbansal8ef1d3e2016-02-03 04:05:4210232 HttpRequestInfo request;
10233
10234 request.method = "GET";
10235 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010236 request.traffic_annotation =
10237 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210238
10239 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:4910240 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10241 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210242 BoundTestNetLog log;
10243 session_deps_.net_log = log.bound().net_log();
10244
10245 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210246 session_deps_.proxy_resolution_service->SetProxyDelegate(
10247 proxy_delegate.get());
tbansal8ef1d3e2016-02-03 04:05:4210248
danakj1fd259a02016-04-16 03:17:0910249 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:4210250
Ryan Hamilton0239aac2018-05-19 00:03:1310251 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510252 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310253 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510254 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:4210255
10256 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110257 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510258 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:4210259 };
10260
Ryan Hamilton0239aac2018-05-19 00:03:1310261 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:1510262 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210263
Ryan Hamilton0239aac2018-05-19 00:03:1310264 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:3310265 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:4910266
Ryan Hamilton0239aac2018-05-19 00:03:1310267 spdy::SpdySerializedFrame stream1_body(
10268 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210269
Ryan Hamilton0239aac2018-05-19 00:03:1310270 spdy::SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:1510271 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210272
Ryan Hamilton0239aac2018-05-19 00:03:1310273 spdy::SpdySerializedFrame stream2_body(
10274 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210275
10276 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110277 CreateMockRead(stream1_reply, 1, ASYNC),
10278 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510279 CreateMockRead(stream1_body, 4, ASYNC),
10280 CreateMockRead(stream2_body, 5, ASYNC),
10281 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:4210282 };
10283
Ryan Sleevib8d7ea02018-05-07 20:01:0110284 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
tbansal8ef1d3e2016-02-03 04:05:4210285 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10286 // Negotiate SPDY to the proxy
10287 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610288 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:4210289 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
10290
bnc87dcefc2017-05-25 12:47:5810291 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910292 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:4210293 TestCompletionCallback callback;
10294 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110295 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:4210296
10297 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110298 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210299 const HttpResponseInfo* response = trans->GetResponseInfo();
10300
wezca1070932016-05-26 20:30:5210301 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:4210302 EXPECT_TRUE(response->headers->IsKeepAlive());
10303
10304 EXPECT_EQ(200, response->headers->response_code());
10305 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10306
10307 std::string response_data;
10308 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110309 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210310 EXPECT_EQ("hello!", response_data);
10311
10312 trans.reset();
10313 session->CloseAllConnections();
10314}
10315
[email protected]2df19bb2010-08-25 20:13:4610316// Test HTTPS connections to a site with a bad certificate, going through an
10317// HTTPS proxy
bncd16676a2016-07-20 16:23:0110318TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:4910319 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10320 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610321
10322 HttpRequestInfo request;
10323 request.method = "GET";
bncce36dca22015-04-21 22:11:2310324 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010325 request.traffic_annotation =
10326 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610327
10328 // Attempt to fetch the URL from a server with a bad cert
10329 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710330 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10331 "Host: www.example.org:443\r\n"
10332 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610333 };
10334
10335 MockRead bad_cert_reads[] = {
10336 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610337 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:4610338 };
10339
10340 // Attempt to fetch the URL with a good cert
10341 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710342 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10343 "Host: www.example.org:443\r\n"
10344 "Proxy-Connection: keep-alive\r\n\r\n"),
10345 MockWrite("GET / HTTP/1.1\r\n"
10346 "Host: www.example.org\r\n"
10347 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610348 };
10349
10350 MockRead good_cert_reads[] = {
10351 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
10352 MockRead("HTTP/1.0 200 OK\r\n"),
10353 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10354 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610355 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:4610356 };
10357
Ryan Sleevib8d7ea02018-05-07 20:01:0110358 StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
10359 StaticSocketDataProvider data(good_cert_reads, good_data_writes);
[email protected]8ddf8322012-02-23 18:08:0610360 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
10361 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:4610362
10363 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:0710364 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10365 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
10366 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:4610367
10368 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:0710369 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10370 session_deps_.socket_factory->AddSocketDataProvider(&data);
10371 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:4610372
[email protected]49639fa2011-12-20 23:22:4110373 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:4610374
danakj1fd259a02016-04-16 03:17:0910375 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610376 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:4610377
tfarina42834112016-09-22 13:38:2010378 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610380
10381 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110382 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:4610383
bnc691fda62016-08-12 00:43:1610384 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:0110385 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610386
10387 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110388 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:4610389
bnc691fda62016-08-12 00:43:1610390 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:4610391
wezca1070932016-05-26 20:30:5210392 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:4610393 EXPECT_EQ(100, response->headers->GetContentLength());
10394}
10395
bncd16676a2016-07-20 16:23:0110396TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:4210397 HttpRequestInfo request;
10398 request.method = "GET";
bncce36dca22015-04-21 22:11:2310399 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310400 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10401 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:1010402 request.traffic_annotation =
10403 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210404
danakj1fd259a02016-04-16 03:17:0910405 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610406 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710407
[email protected]1c773ea12009-04-28 19:58:4210408 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310409 MockWrite(
10410 "GET / HTTP/1.1\r\n"
10411 "Host: www.example.org\r\n"
10412 "Connection: keep-alive\r\n"
10413 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210414 };
10415
10416 // Lastly, the server responds with the actual content.
10417 MockRead data_reads[] = {
10418 MockRead("HTTP/1.0 200 OK\r\n"),
10419 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10420 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610421 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210422 };
10423
Ryan Sleevib8d7ea02018-05-07 20:01:0110424 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710425 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210426
[email protected]49639fa2011-12-20 23:22:4110427 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210428
tfarina42834112016-09-22 13:38:2010429 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110430 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210431
10432 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110433 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210434}
10435
bncd16676a2016-07-20 16:23:0110436TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
Matt Menked732ea42019-03-08 12:05:0010437 // Test user agent values, used both for the request header of the original
10438 // request, and the value returned by the HttpUserAgentSettings. nullptr means
10439 // no request header / no HttpUserAgentSettings object.
10440 const char* kTestUserAgents[] = {nullptr, "", "Foopy"};
[email protected]da81f132010-08-18 23:39:2910441
Matt Menked732ea42019-03-08 12:05:0010442 for (const char* setting_user_agent : kTestUserAgents) {
10443 if (!setting_user_agent) {
10444 session_deps_.http_user_agent_settings.reset();
10445 } else {
10446 session_deps_.http_user_agent_settings =
10447 std::make_unique<StaticHttpUserAgentSettings>(
10448 std::string() /* accept-language */, setting_user_agent);
10449 }
10450 session_deps_.proxy_resolution_service =
10451 ProxyResolutionService::CreateFixed("myproxy:70",
10452 TRAFFIC_ANNOTATION_FOR_TESTS);
10453 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10454 for (const char* request_user_agent : kTestUserAgents) {
10455 HttpRequestInfo request;
10456 request.method = "GET";
10457 request.url = GURL("https://www.example.org/");
10458 if (request_user_agent) {
10459 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10460 request_user_agent);
10461 }
10462 request.traffic_annotation =
10463 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710464
Matt Menked732ea42019-03-08 12:05:0010465 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]da81f132010-08-18 23:39:2910466
Matt Menked732ea42019-03-08 12:05:0010467 std::string expected_request;
10468 if (!setting_user_agent || strlen(setting_user_agent) == 0) {
10469 expected_request =
10470 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10471 "Host: www.example.org:443\r\n"
10472 "Proxy-Connection: keep-alive\r\n\r\n";
10473 } else {
10474 expected_request = base::StringPrintf(
10475 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10476 "Host: www.example.org:443\r\n"
10477 "Proxy-Connection: keep-alive\r\n"
10478 "User-Agent: %s\r\n\r\n",
10479 setting_user_agent);
10480 }
10481 MockWrite data_writes[] = {
10482 MockWrite(expected_request.c_str()),
10483 };
10484 MockRead data_reads[] = {
10485 // Return an error, so the transaction stops here (this test isn't
10486 // interested in the rest).
10487 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
10488 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10489 MockRead("Proxy-Connection: close\r\n\r\n"),
10490 };
[email protected]da81f132010-08-18 23:39:2910491
Matt Menked732ea42019-03-08 12:05:0010492 StaticSocketDataProvider data(data_reads, data_writes);
10493 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:2910494
Matt Menked732ea42019-03-08 12:05:0010495 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:2910496
Matt Menked732ea42019-03-08 12:05:0010497 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10498 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10499
10500 rv = callback.WaitForResult();
10501 EXPECT_THAT(rv, IsOk());
10502 }
10503 }
[email protected]da81f132010-08-18 23:39:2910504}
10505
bncd16676a2016-07-20 16:23:0110506TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:4210507 HttpRequestInfo request;
10508 request.method = "GET";
bncce36dca22015-04-21 22:11:2310509 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:1610510 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
10511 "http://the.previous.site.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010512 request.traffic_annotation =
10513 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210514
danakj1fd259a02016-04-16 03:17:0910515 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610516 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710517
[email protected]1c773ea12009-04-28 19:58:4210518 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310519 MockWrite(
10520 "GET / HTTP/1.1\r\n"
10521 "Host: www.example.org\r\n"
10522 "Connection: keep-alive\r\n"
10523 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210524 };
10525
10526 // Lastly, the server responds with the actual content.
10527 MockRead data_reads[] = {
10528 MockRead("HTTP/1.0 200 OK\r\n"),
10529 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10530 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610531 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210532 };
10533
Ryan Sleevib8d7ea02018-05-07 20:01:0110534 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710535 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210536
[email protected]49639fa2011-12-20 23:22:4110537 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210538
tfarina42834112016-09-22 13:38:2010539 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110540 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210541
10542 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110543 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210544}
10545
bncd16676a2016-07-20 16:23:0110546TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210547 HttpRequestInfo request;
10548 request.method = "POST";
bncce36dca22015-04-21 22:11:2310549 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010550 request.traffic_annotation =
10551 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210552
danakj1fd259a02016-04-16 03:17:0910553 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610554 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710555
[email protected]1c773ea12009-04-28 19:58:4210556 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310557 MockWrite(
10558 "POST / HTTP/1.1\r\n"
10559 "Host: www.example.org\r\n"
10560 "Connection: keep-alive\r\n"
10561 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210562 };
10563
10564 // Lastly, the server responds with the actual content.
10565 MockRead data_reads[] = {
10566 MockRead("HTTP/1.0 200 OK\r\n"),
10567 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10568 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610569 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210570 };
10571
Ryan Sleevib8d7ea02018-05-07 20:01:0110572 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710573 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210574
[email protected]49639fa2011-12-20 23:22:4110575 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210576
tfarina42834112016-09-22 13:38:2010577 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110578 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210579
10580 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110581 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210582}
10583
bncd16676a2016-07-20 16:23:0110584TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210585 HttpRequestInfo request;
10586 request.method = "PUT";
bncce36dca22015-04-21 22:11:2310587 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010588 request.traffic_annotation =
10589 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210590
danakj1fd259a02016-04-16 03:17:0910591 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610592 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710593
[email protected]1c773ea12009-04-28 19:58:4210594 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310595 MockWrite(
10596 "PUT / HTTP/1.1\r\n"
10597 "Host: www.example.org\r\n"
10598 "Connection: keep-alive\r\n"
10599 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210600 };
10601
10602 // Lastly, the server responds with the actual content.
10603 MockRead data_reads[] = {
10604 MockRead("HTTP/1.0 200 OK\r\n"),
10605 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10606 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610607 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210608 };
10609
Ryan Sleevib8d7ea02018-05-07 20:01:0110610 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710611 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210612
[email protected]49639fa2011-12-20 23:22:4110613 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210614
tfarina42834112016-09-22 13:38:2010615 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110616 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210617
10618 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110619 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210620}
10621
bncd16676a2016-07-20 16:23:0110622TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210623 HttpRequestInfo request;
10624 request.method = "HEAD";
bncce36dca22015-04-21 22:11:2310625 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010626 request.traffic_annotation =
10627 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210628
danakj1fd259a02016-04-16 03:17:0910629 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610630 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710631
[email protected]1c773ea12009-04-28 19:58:4210632 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:1310633 MockWrite("HEAD / HTTP/1.1\r\n"
10634 "Host: www.example.org\r\n"
10635 "Connection: keep-alive\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_CacheControlNoCache) {
[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_BYPASS_CACHE;
Ramin Halavatib5e433e2018-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 "Pragma: no-cache\r\n"
10675 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210676 };
10677
10678 // Lastly, the server responds with the actual content.
10679 MockRead data_reads[] = {
10680 MockRead("HTTP/1.0 200 OK\r\n"),
10681 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10682 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610683 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210684 };
10685
Ryan Sleevib8d7ea02018-05-07 20:01:0110686 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710687 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210688
[email protected]49639fa2011-12-20 23:22:4110689 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210690
tfarina42834112016-09-22 13:38:2010691 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110692 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210693
10694 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110695 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210696}
10697
bncd16676a2016-07-20 16:23:0110698TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:4210699 HttpRequestInfo request;
10700 request.method = "GET";
bncce36dca22015-04-21 22:11:2310701 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210702 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:1010703 request.traffic_annotation =
10704 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210705
danakj1fd259a02016-04-16 03:17:0910706 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610707 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710708
[email protected]1c773ea12009-04-28 19:58:4210709 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310710 MockWrite(
10711 "GET / HTTP/1.1\r\n"
10712 "Host: www.example.org\r\n"
10713 "Connection: keep-alive\r\n"
10714 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210715 };
10716
10717 // Lastly, the server responds with the actual content.
10718 MockRead data_reads[] = {
10719 MockRead("HTTP/1.0 200 OK\r\n"),
10720 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10721 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610722 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210723 };
10724
Ryan Sleevib8d7ea02018-05-07 20:01:0110725 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710726 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210727
[email protected]49639fa2011-12-20 23:22:4110728 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210729
tfarina42834112016-09-22 13:38:2010730 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110731 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210732
10733 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110734 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210735}
10736
bncd16676a2016-07-20 16:23:0110737TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:4210738 HttpRequestInfo request;
10739 request.method = "GET";
bncce36dca22015-04-21 22:11:2310740 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310741 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e2018-02-07 07:41:1010742 request.traffic_annotation =
10743 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210744
danakj1fd259a02016-04-16 03:17:0910745 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610746 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710747
[email protected]1c773ea12009-04-28 19:58:4210748 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310749 MockWrite(
10750 "GET / HTTP/1.1\r\n"
10751 "Host: www.example.org\r\n"
10752 "Connection: keep-alive\r\n"
10753 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210754 };
10755
10756 // Lastly, the server responds with the actual content.
10757 MockRead data_reads[] = {
10758 MockRead("HTTP/1.0 200 OK\r\n"),
10759 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10760 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610761 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210762 };
10763
Ryan Sleevib8d7ea02018-05-07 20:01:0110764 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710765 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210766
[email protected]49639fa2011-12-20 23:22:4110767 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210768
tfarina42834112016-09-22 13:38:2010769 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110770 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210771
10772 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110773 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210774}
10775
bncd16676a2016-07-20 16:23:0110776TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:4710777 HttpRequestInfo request;
10778 request.method = "GET";
bncce36dca22015-04-21 22:11:2310779 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310780 request.extra_headers.SetHeader("referer", "www.foo.com");
10781 request.extra_headers.SetHeader("hEllo", "Kitty");
10782 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1010783 request.traffic_annotation =
10784 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:4710785
danakj1fd259a02016-04-16 03:17:0910786 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610787 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710788
[email protected]270c6412010-03-29 22:02:4710789 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310790 MockWrite(
10791 "GET / HTTP/1.1\r\n"
10792 "Host: www.example.org\r\n"
10793 "Connection: keep-alive\r\n"
10794 "referer: www.foo.com\r\n"
10795 "hEllo: Kitty\r\n"
10796 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:4710797 };
10798
10799 // Lastly, the server responds with the actual content.
10800 MockRead data_reads[] = {
10801 MockRead("HTTP/1.0 200 OK\r\n"),
10802 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10803 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610804 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:4710805 };
10806
Ryan Sleevib8d7ea02018-05-07 20:01:0110807 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710808 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:4710809
[email protected]49639fa2011-12-20 23:22:4110810 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:4710811
tfarina42834112016-09-22 13:38:2010812 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110813 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:4710814
10815 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110816 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:4710817}
10818
bncd16676a2016-07-20 16:23:0110819TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710820 HttpRequestInfo request;
10821 request.method = "GET";
bncce36dca22015-04-21 22:11:2310822 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010823 request.traffic_annotation =
10824 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710825
Lily Houghton8c2f97d2018-01-22 05:06:5910826 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910827 ProxyResolutionService::CreateFixedFromPacResult(
10828 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110829 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710830 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210831
danakj1fd259a02016-04-16 03:17:0910832 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610833 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210834
[email protected]3cd17242009-06-23 02:59:0210835 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10836 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10837
10838 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410839 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10840 MockWrite("GET / HTTP/1.1\r\n"
10841 "Host: www.example.org\r\n"
10842 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210843
10844 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410845 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10846 MockRead("HTTP/1.0 200 OK\r\n"),
10847 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10848 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0210849
Ryan Sleevib8d7ea02018-05-07 20:01:0110850 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710851 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210852
[email protected]49639fa2011-12-20 23:22:4110853 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210854
tfarina42834112016-09-22 13:38:2010855 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110856 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210857
10858 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110859 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210860
bnc691fda62016-08-12 00:43:1610861 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210862 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:0210863
tbansal2ecbbc72016-10-06 17:15:4710864 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:2010865 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610866 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010867 TestLoadTimingNotReusedWithPac(load_timing_info,
10868 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10869
[email protected]3cd17242009-06-23 02:59:0210870 std::string response_text;
bnc691fda62016-08-12 00:43:1610871 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110872 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210873 EXPECT_EQ("Payload", response_text);
10874}
10875
bncd16676a2016-07-20 16:23:0110876TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710877 HttpRequestInfo request;
10878 request.method = "GET";
bncce36dca22015-04-21 22:11:2310879 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010880 request.traffic_annotation =
10881 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710882
Lily Houghton8c2f97d2018-01-22 05:06:5910883 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910884 ProxyResolutionService::CreateFixedFromPacResult(
10885 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110886 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710887 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210888
danakj1fd259a02016-04-16 03:17:0910889 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610890 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210891
[email protected]3cd17242009-06-23 02:59:0210892 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
10893 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10894
10895 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310896 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
Avi Drissman4365a4782018-12-28 19:26:2410897 base::size(write_buffer)),
10898 MockWrite("GET / HTTP/1.1\r\n"
10899 "Host: www.example.org\r\n"
10900 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210901
10902 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410903 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
10904 base::size(read_buffer)),
10905 MockRead("HTTP/1.0 200 OK\r\n"),
10906 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10907 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3510908
Ryan Sleevib8d7ea02018-05-07 20:01:0110909 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710910 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510911
[email protected]8ddf8322012-02-23 18:08:0610912 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710913 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:3510914
[email protected]49639fa2011-12-20 23:22:4110915 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510916
tfarina42834112016-09-22 13:38:2010917 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110918 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510919
10920 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110921 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510922
[email protected]029c83b62013-01-24 05:28:2010923 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610924 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010925 TestLoadTimingNotReusedWithPac(load_timing_info,
10926 CONNECT_TIMING_HAS_SSL_TIMES);
10927
bnc691fda62016-08-12 00:43:1610928 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210929 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710930 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510931
10932 std::string response_text;
bnc691fda62016-08-12 00:43:1610933 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110934 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510935 EXPECT_EQ("Payload", response_text);
10936}
10937
bncd16676a2016-07-20 16:23:0110938TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:2010939 HttpRequestInfo request;
10940 request.method = "GET";
bncce36dca22015-04-21 22:11:2310941 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010942 request.traffic_annotation =
10943 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:2010944
Ramin Halavatica8d5252018-03-12 05:33:4910945 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10946 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110947 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710948 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:2010949
danakj1fd259a02016-04-16 03:17:0910950 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610951 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:2010952
10953 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10954 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10955
10956 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410957 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10958 MockWrite("GET / HTTP/1.1\r\n"
10959 "Host: www.example.org\r\n"
10960 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:2010961
10962 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410963 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10964 MockRead("HTTP/1.0 200 OK\r\n"),
10965 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10966 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]029c83b62013-01-24 05:28:2010967
Ryan Sleevib8d7ea02018-05-07 20:01:0110968 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710969 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:2010970
10971 TestCompletionCallback callback;
10972
tfarina42834112016-09-22 13:38:2010973 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110974 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:2010975
10976 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110977 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010978
bnc691fda62016-08-12 00:43:1610979 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210980 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:2010981
10982 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610983 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010984 TestLoadTimingNotReused(load_timing_info,
10985 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10986
10987 std::string response_text;
bnc691fda62016-08-12 00:43:1610988 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110989 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010990 EXPECT_EQ("Payload", response_text);
10991}
10992
bncd16676a2016-07-20 16:23:0110993TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710994 HttpRequestInfo request;
10995 request.method = "GET";
bncce36dca22015-04-21 22:11:2310996 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010997 request.traffic_annotation =
10998 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710999
Lily Houghton8c2f97d2018-01-22 05:06:5911000 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911001 ProxyResolutionService::CreateFixedFromPacResult(
11002 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111003 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711004 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3511005
danakj1fd259a02016-04-16 03:17:0911006 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611007 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3511008
[email protected]e0c27be2009-07-15 13:09:3511009 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
11010 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3711011 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2311012 0x05, // Version
11013 0x01, // Command (CONNECT)
11014 0x00, // Reserved.
11015 0x03, // Address type (DOMAINNAME).
11016 0x0F, // Length of domain (15)
11017 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
11018 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3711019 };
[email protected]e0c27be2009-07-15 13:09:3511020 const char kSOCKS5OkResponse[] =
11021 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
11022
11023 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411024 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
11025 MockWrite(ASYNC, kSOCKS5OkRequest, base::size(kSOCKS5OkRequest)),
11026 MockWrite("GET / HTTP/1.1\r\n"
11027 "Host: www.example.org\r\n"
11028 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3511029
11030 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411031 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11032 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11033 MockRead("HTTP/1.0 200 OK\r\n"),
11034 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11035 MockRead("Payload"),
11036 MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3511037
Ryan Sleevib8d7ea02018-05-07 20:01:0111038 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711039 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3511040
[email protected]49639fa2011-12-20 23:22:4111041 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3511042
tfarina42834112016-09-22 13:38:2011043 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111044 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3511045
11046 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111047 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3511048
bnc691fda62016-08-12 00:43:1611049 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211050 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711051 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3511052
[email protected]029c83b62013-01-24 05:28:2011053 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611054 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011055 TestLoadTimingNotReusedWithPac(load_timing_info,
11056 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
11057
[email protected]e0c27be2009-07-15 13:09:3511058 std::string response_text;
bnc691fda62016-08-12 00:43:1611059 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111060 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3511061 EXPECT_EQ("Payload", response_text);
11062}
11063
bncd16676a2016-07-20 16:23:0111064TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2711065 HttpRequestInfo request;
11066 request.method = "GET";
bncce36dca22015-04-21 22:11:2311067 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011068 request.traffic_annotation =
11069 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711070
Lily Houghton8c2f97d2018-01-22 05:06:5911071 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911072 ProxyResolutionService::CreateFixedFromPacResult(
11073 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111074 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711075 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3511076
danakj1fd259a02016-04-16 03:17:0911077 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611078 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3511079
[email protected]e0c27be2009-07-15 13:09:3511080 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
11081 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3711082 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2311083 0x05, // Version
11084 0x01, // Command (CONNECT)
11085 0x00, // Reserved.
11086 0x03, // Address type (DOMAINNAME).
11087 0x0F, // Length of domain (15)
11088 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
11089 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3711090 };
11091
[email protected]e0c27be2009-07-15 13:09:3511092 const char kSOCKS5OkResponse[] =
11093 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
11094
11095 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411096 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
bncce36dca22015-04-21 22:11:2311097 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
Avi Drissman4365a4782018-12-28 19:26:2411098 base::size(kSOCKS5OkRequest)),
11099 MockWrite("GET / HTTP/1.1\r\n"
11100 "Host: www.example.org\r\n"
11101 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3511102
11103 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411104 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11105 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11106 MockRead("HTTP/1.0 200 OK\r\n"),
11107 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11108 MockRead("Payload"),
11109 MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0211110
Ryan Sleevib8d7ea02018-05-07 20:01:0111111 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711112 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0211113
[email protected]8ddf8322012-02-23 18:08:0611114 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711115 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0211116
[email protected]49639fa2011-12-20 23:22:4111117 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0211118
tfarina42834112016-09-22 13:38:2011119 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111120 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0211121
11122 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111123 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211124
bnc691fda62016-08-12 00:43:1611125 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211126 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711127 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0211128
[email protected]029c83b62013-01-24 05:28:2011129 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611130 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011131 TestLoadTimingNotReusedWithPac(load_timing_info,
11132 CONNECT_TIMING_HAS_SSL_TIMES);
11133
[email protected]3cd17242009-06-23 02:59:0211134 std::string response_text;
bnc691fda62016-08-12 00:43:1611135 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111136 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211137 EXPECT_EQ("Payload", response_text);
11138}
11139
[email protected]448d4ca52012-03-04 04:12:2311140namespace {
11141
Matt Menkef6edce752019-03-19 17:21:5611142// Tests that for connection endpoints the group ids are correctly set.
[email protected]2d731a32010-04-29 01:04:0611143
Matt Menkef6edce752019-03-19 17:21:5611144struct GroupIdTest {
[email protected]2d731a32010-04-29 01:04:0611145 std::string proxy_server;
11146 std::string url;
Matt Menkef6edce752019-03-19 17:21:5611147 ClientSocketPool::GroupId expected_group_id;
[email protected]e60e47a2010-07-14 03:37:1811148 bool ssl;
[email protected]2d731a32010-04-29 01:04:0611149};
11150
Matt Menkef6edce752019-03-19 17:21:5611151std::unique_ptr<HttpNetworkSession> SetupSessionForGroupIdTests(
[email protected]bb88e1d32013-05-03 23:11:0711152 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0911153 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0611154
bnc525e175a2016-06-20 12:36:4011155 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311156 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111157 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1211158 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111159 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4211160 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4611161 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0611162
11163 return session;
11164}
11165
Matt Menkef6edce752019-03-19 17:21:5611166int GroupIdTransactionHelper(const std::string& url,
11167 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0611168 HttpRequestInfo request;
11169 request.method = "GET";
11170 request.url = GURL(url);
Ramin Halavatib5e433e2018-02-07 07:41:1011171 request.traffic_annotation =
11172 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0611173
bnc691fda62016-08-12 00:43:1611174 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2711175
[email protected]49639fa2011-12-20 23:22:4111176 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0611177
11178 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2011179 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0611180}
11181
[email protected]448d4ca52012-03-04 04:12:2311182} // namespace
11183
Matt Menkef6edce752019-03-19 17:21:5611184TEST_F(HttpNetworkTransactionTest, GroupIdForDirectConnections) {
11185 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311186 {
Matt Menkef6edce752019-03-19 17:21:5611187 "", // unused
11188 "http://www.example.org/direct",
11189 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11190 ClientSocketPool::SocketType::kHttp,
Matt Menkebdf777802019-04-22 19:38:5911191 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menkef6edce752019-03-19 17:21:5611192 false,
bncce36dca22015-04-21 22:11:2311193 },
11194 {
Matt Menkef6edce752019-03-19 17:21:5611195 "", // unused
11196 "http://[2001:1418:13:1::25]/direct",
11197 ClientSocketPool::GroupId(HostPortPair("2001:1418:13:1::25", 80),
11198 ClientSocketPool::SocketType::kHttp,
Matt Menkebdf777802019-04-22 19:38:5911199 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menkef6edce752019-03-19 17:21:5611200 false,
bncce36dca22015-04-21 22:11:2311201 },
[email protected]04e5be32009-06-26 20:00:3111202
bncce36dca22015-04-21 22:11:2311203 // SSL Tests
11204 {
Matt Menkef6edce752019-03-19 17:21:5611205 "", // unused
11206 "https://www.example.org/direct_ssl",
11207 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11208 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911209 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menkef6edce752019-03-19 17:21:5611210 true,
bncce36dca22015-04-21 22:11:2311211 },
11212 {
Matt Menkef6edce752019-03-19 17:21:5611213 "", // unused
11214 "https://[2001:1418:13:1::25]/direct",
11215 ClientSocketPool::GroupId(HostPortPair("2001:1418:13:1::25", 443),
11216 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911217 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menkef6edce752019-03-19 17:21:5611218 true,
bncce36dca22015-04-21 22:11:2311219 },
11220 {
Matt Menkef6edce752019-03-19 17:21:5611221 "", // unused
11222 "https://host.with.alternate/direct",
11223 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11224 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911225 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menkef6edce752019-03-19 17:21:5611226 true,
bncce36dca22015-04-21 22:11:2311227 },
[email protected]2d731a32010-04-29 01:04:0611228 };
[email protected]2ff8b312010-04-26 22:20:5411229
Avi Drissman4365a4782018-12-28 19:26:2411230 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911231 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911232 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11233 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911234 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611235 SetupSessionForGroupIdTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611236
mmenkee65e7af2015-10-13 17:16:4211237 HttpNetworkSessionPeer peer(session.get());
Matt Menkef6edce752019-03-19 17:21:5611238 CaptureGroupIdTransportSocketPool* transport_conn_pool =
Matt Menked6fd2a52019-03-20 06:14:3611239 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911240 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011241 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
11242 base::WrapUnique(transport_conn_pool));
dchengc7eeda422015-12-26 03:56:4811243 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611244
11245 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611246 GroupIdTransactionHelper(tests[i].url, session.get()));
11247 EXPECT_EQ(tests[i].expected_group_id,
11248 transport_conn_pool->last_group_id_received());
Matt Menke9d5e2c92019-02-05 01:42:2311249 EXPECT_TRUE(transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0611250 }
[email protected]2d731a32010-04-29 01:04:0611251}
11252
Matt Menkef6edce752019-03-19 17:21:5611253TEST_F(HttpNetworkTransactionTest, GroupIdForHTTPProxyConnections) {
11254 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311255 {
Matt Menke4802de62019-03-08 22:47:5011256 "http_proxy",
11257 "http://www.example.org/http_proxy_normal",
Matt Menkef6edce752019-03-19 17:21:5611258 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11259 ClientSocketPool::SocketType::kHttp,
Matt Menkebdf777802019-04-22 19:38:5911260 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011261 false,
bncce36dca22015-04-21 22:11:2311262 },
[email protected]2d731a32010-04-29 01:04:0611263
bncce36dca22015-04-21 22:11:2311264 // SSL Tests
11265 {
Matt Menke4802de62019-03-08 22:47:5011266 "http_proxy",
11267 "https://www.example.org/http_connect_ssl",
Matt Menkef6edce752019-03-19 17:21:5611268 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11269 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911270 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011271 true,
bncce36dca22015-04-21 22:11:2311272 },
[email protected]af3490e2010-10-16 21:02:2911273
bncce36dca22015-04-21 22:11:2311274 {
Matt Menke4802de62019-03-08 22:47:5011275 "http_proxy",
11276 "https://host.with.alternate/direct",
Matt Menkef6edce752019-03-19 17:21:5611277 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11278 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911279 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011280 true,
bncce36dca22015-04-21 22:11:2311281 },
[email protected]45499252013-01-23 17:12:5611282
bncce36dca22015-04-21 22:11:2311283 {
Matt Menke4802de62019-03-08 22:47:5011284 "http_proxy",
11285 "ftp://ftp.google.com/http_proxy_normal",
Matt Menkef6edce752019-03-19 17:21:5611286 ClientSocketPool::GroupId(HostPortPair("ftp.google.com", 21),
11287 ClientSocketPool::SocketType::kFtp,
Matt Menkebdf777802019-04-22 19:38:5911288 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011289 false,
bncce36dca22015-04-21 22:11:2311290 },
[email protected]2d731a32010-04-29 01:04:0611291 };
11292
Avi Drissman4365a4782018-12-28 19:26:2411293 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911294 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911295 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11296 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911297 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611298 SetupSessionForGroupIdTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611299
mmenkee65e7af2015-10-13 17:16:4211300 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0611301
Matt Menkee8648fa2019-01-17 16:47:0711302 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11303 HostPortPair("http_proxy", 80));
Matt Menkef6edce752019-03-19 17:21:5611304 CaptureGroupIdTransportSocketPool* http_proxy_pool =
Matt Menked6fd2a52019-03-20 06:14:3611305 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911306 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011307 mock_pool_manager->SetSocketPool(proxy_server,
11308 base::WrapUnique(http_proxy_pool));
dchengc7eeda422015-12-26 03:56:4811309 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611310
11311 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611312 GroupIdTransactionHelper(tests[i].url, session.get()));
11313 EXPECT_EQ(tests[i].expected_group_id,
11314 http_proxy_pool->last_group_id_received());
[email protected]2d731a32010-04-29 01:04:0611315 }
[email protected]2d731a32010-04-29 01:04:0611316}
11317
Matt Menkef6edce752019-03-19 17:21:5611318TEST_F(HttpNetworkTransactionTest, GroupIdForSOCKSConnections) {
11319 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311320 {
Matt Menke4802de62019-03-08 22:47:5011321 "socks4://socks_proxy:1080",
11322 "http://www.example.org/socks4_direct",
Matt Menkef6edce752019-03-19 17:21:5611323 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11324 ClientSocketPool::SocketType::kHttp,
Matt Menkebdf777802019-04-22 19:38:5911325 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011326 false,
bncce36dca22015-04-21 22:11:2311327 },
11328 {
Matt Menke4802de62019-03-08 22:47:5011329 "socks5://socks_proxy:1080",
11330 "http://www.example.org/socks5_direct",
Matt Menkef6edce752019-03-19 17:21:5611331 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11332 ClientSocketPool::SocketType::kHttp,
Matt Menkebdf777802019-04-22 19:38:5911333 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011334 false,
bncce36dca22015-04-21 22:11:2311335 },
[email protected]2d731a32010-04-29 01:04:0611336
bncce36dca22015-04-21 22:11:2311337 // SSL Tests
11338 {
Matt Menke4802de62019-03-08 22:47:5011339 "socks4://socks_proxy:1080",
11340 "https://www.example.org/socks4_ssl",
Matt Menkef6edce752019-03-19 17:21:5611341 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11342 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911343 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011344 true,
bncce36dca22015-04-21 22:11:2311345 },
11346 {
Matt Menke4802de62019-03-08 22:47:5011347 "socks5://socks_proxy:1080",
11348 "https://www.example.org/socks5_ssl",
Matt Menkef6edce752019-03-19 17:21:5611349 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11350 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911351 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011352 true,
bncce36dca22015-04-21 22:11:2311353 },
[email protected]af3490e2010-10-16 21:02:2911354
bncce36dca22015-04-21 22:11:2311355 {
Matt Menke4802de62019-03-08 22:47:5011356 "socks4://socks_proxy:1080",
11357 "https://host.with.alternate/direct",
Matt Menkef6edce752019-03-19 17:21:5611358 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11359 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911360 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011361 true,
bncce36dca22015-04-21 22:11:2311362 },
[email protected]04e5be32009-06-26 20:00:3111363 };
11364
Avi Drissman4365a4782018-12-28 19:26:2411365 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911366 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911367 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11368 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911369 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611370 SetupSessionForGroupIdTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0211371
mmenkee65e7af2015-10-13 17:16:4211372 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3111373
Matt Menkee8648fa2019-01-17 16:47:0711374 ProxyServer proxy_server(
11375 ProxyServer::FromURI(tests[i].proxy_server, ProxyServer::SCHEME_HTTP));
11376 ASSERT_TRUE(proxy_server.is_valid());
Matt Menkef6edce752019-03-19 17:21:5611377 CaptureGroupIdTransportSocketPool* socks_conn_pool =
Matt Menked6fd2a52019-03-20 06:14:3611378 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911379 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011380 mock_pool_manager->SetSocketPool(proxy_server,
11381 base::WrapUnique(socks_conn_pool));
dchengc7eeda422015-12-26 03:56:4811382 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3111383
bnc691fda62016-08-12 00:43:1611384 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3111385
[email protected]2d731a32010-04-29 01:04:0611386 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611387 GroupIdTransactionHelper(tests[i].url, session.get()));
11388 EXPECT_EQ(tests[i].expected_group_id,
11389 socks_conn_pool->last_group_id_received());
[email protected]04e5be32009-06-26 20:00:3111390 }
11391}
11392
bncd16676a2016-07-20 16:23:0111393TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2711394 HttpRequestInfo request;
11395 request.method = "GET";
bncce36dca22015-04-21 22:11:2311396 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011397 request.traffic_annotation =
11398 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711399
Ramin Halavatica8d5252018-03-12 05:33:4911400 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11401 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3211402
[email protected]69719062010-01-05 20:09:2111403 // This simulates failure resolving all hostnames; that means we will fail
11404 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0711405 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3211406
danakj1fd259a02016-04-16 03:17:0911407 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611408 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2511409
[email protected]49639fa2011-12-20 23:22:4111410 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2511411
tfarina42834112016-09-22 13:38:2011412 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111413 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2511414
[email protected]9172a982009-06-06 00:30:2511415 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111416 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2511417}
11418
[email protected]0877e3d2009-10-17 22:29:5711419// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0111420TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5711421 HttpRequestInfo request;
11422 request.method = "GET";
11423 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1011424 request.traffic_annotation =
11425 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711426
11427 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0611428 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711429 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111430 StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
[email protected]bb88e1d32013-05-03 23:11:0711431 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911432 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711433
[email protected]49639fa2011-12-20 23:22:4111434 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711435
bnc691fda62016-08-12 00:43:1611436 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711437
tfarina42834112016-09-22 13:38:2011438 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111439 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711440
11441 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111442 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5911443
11444 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611445 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911446 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711447}
11448
zmo9528c9f42015-08-04 22:12:0811449// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0111450TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5711451 HttpRequestInfo request;
11452 request.method = "GET";
11453 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1011454 request.traffic_annotation =
11455 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711456
11457 MockRead data_reads[] = {
11458 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0611459 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711460 };
11461
Ryan Sleevib8d7ea02018-05-07 20:01:0111462 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711463 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911464 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711465
[email protected]49639fa2011-12-20 23:22:4111466 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711467
bnc691fda62016-08-12 00:43:1611468 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711469
tfarina42834112016-09-22 13:38:2011470 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111471 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711472
11473 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111474 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811475
bnc691fda62016-08-12 00:43:1611476 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211477 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0811478
wezca1070932016-05-26 20:30:5211479 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0811480 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11481
11482 std::string response_data;
bnc691fda62016-08-12 00:43:1611483 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111484 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811485 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5911486
11487 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611488 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911489 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711490}
11491
11492// Make sure that a dropped connection while draining the body for auth
11493// restart does the right thing.
bncd16676a2016-07-20 16:23:0111494TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5711495 HttpRequestInfo request;
11496 request.method = "GET";
bncce36dca22015-04-21 22:11:2311497 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011498 request.traffic_annotation =
11499 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711500
11501 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311502 MockWrite(
11503 "GET / HTTP/1.1\r\n"
11504 "Host: www.example.org\r\n"
11505 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711506 };
11507
11508 MockRead data_reads1[] = {
11509 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
11510 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
11511 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11512 MockRead("Content-Length: 14\r\n\r\n"),
11513 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0611514 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711515 };
11516
Ryan Sleevib8d7ea02018-05-07 20:01:0111517 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0711518 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5711519
bnc691fda62016-08-12 00:43:1611520 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5711521 // be issuing -- the final header line contains the credentials.
11522 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311523 MockWrite(
11524 "GET / HTTP/1.1\r\n"
11525 "Host: www.example.org\r\n"
11526 "Connection: keep-alive\r\n"
11527 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711528 };
11529
11530 // Lastly, the server responds with the actual content.
11531 MockRead data_reads2[] = {
11532 MockRead("HTTP/1.1 200 OK\r\n"),
11533 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11534 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611535 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711536 };
11537
Ryan Sleevib8d7ea02018-05-07 20:01:0111538 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:0711539 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0911540 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711541
[email protected]49639fa2011-12-20 23:22:4111542 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5711543
bnc691fda62016-08-12 00:43:1611544 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011545
tfarina42834112016-09-22 13:38:2011546 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111547 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711548
11549 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111550 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711551
bnc691fda62016-08-12 00:43:1611552 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211553 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811554 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]0877e3d2009-10-17 22:29:5711555
[email protected]49639fa2011-12-20 23:22:4111556 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5711557
bnc691fda62016-08-12 00:43:1611558 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0111559 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711560
11561 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111562 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711563
bnc691fda62016-08-12 00:43:1611564 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211565 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811566 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0877e3d2009-10-17 22:29:5711567 EXPECT_EQ(100, response->headers->GetContentLength());
11568}
11569
11570// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0111571TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4911572 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11573 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711574
11575 HttpRequestInfo request;
11576 request.method = "GET";
bncce36dca22015-04-21 22:11:2311577 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011578 request.traffic_annotation =
11579 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711580
11581 MockRead proxy_reads[] = {
11582 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0611583 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5711584 };
11585
Ryan Sleevib8d7ea02018-05-07 20:01:0111586 StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
[email protected]8ddf8322012-02-23 18:08:0611587 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5711588
[email protected]bb88e1d32013-05-03 23:11:0711589 session_deps_.socket_factory->AddSocketDataProvider(&data);
11590 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5711591
[email protected]49639fa2011-12-20 23:22:4111592 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711593
[email protected]bb88e1d32013-05-03 23:11:0711594 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5711595
danakj1fd259a02016-04-16 03:17:0911596 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611597 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711598
tfarina42834112016-09-22 13:38:2011599 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111600 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711601
11602 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111603 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5711604}
11605
bncd16676a2016-07-20 16:23:0111606TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4611607 HttpRequestInfo request;
11608 request.method = "GET";
bncce36dca22015-04-21 22:11:2311609 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011610 request.traffic_annotation =
11611 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4611612
danakj1fd259a02016-04-16 03:17:0911613 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611614 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2711615
[email protected]e22e1362009-11-23 21:31:1211616 MockRead data_reads[] = {
11617 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611618 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1211619 };
[email protected]9492e4a2010-02-24 00:58:4611620
Ryan Sleevib8d7ea02018-05-07 20:01:0111621 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711622 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4611623
[email protected]49639fa2011-12-20 23:22:4111624 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4611625
tfarina42834112016-09-22 13:38:2011626 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111627 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4611628
robpercival214763f2016-07-01 23:27:0111629 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4611630
bnc691fda62016-08-12 00:43:1611631 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211632 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4611633
wezca1070932016-05-26 20:30:5211634 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4611635 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11636
11637 std::string response_data;
bnc691fda62016-08-12 00:43:1611638 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111639 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1211640}
11641
bncd16676a2016-07-20 16:23:0111642TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1511643 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5211644 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1411645 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2111646 UploadFileElementReader::ScopedOverridingContentLengthForTests
11647 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3311648
danakj1fd259a02016-04-16 03:17:0911649 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911650 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411651 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0711652 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211653 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711654
11655 HttpRequestInfo request;
11656 request.method = "POST";
bncce36dca22015-04-21 22:11:2311657 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711658 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011659 request.traffic_annotation =
11660 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711661
danakj1fd259a02016-04-16 03:17:0911662 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611663 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3311664
11665 MockRead data_reads[] = {
11666 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11667 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611668 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3311669 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111670 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711671 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3311672
[email protected]49639fa2011-12-20 23:22:4111673 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3311674
tfarina42834112016-09-22 13:38:2011675 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111676 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3311677
11678 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111679 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3311680
bnc691fda62016-08-12 00:43:1611681 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211682 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3311683
maksim.sisove869bf52016-06-23 17:11:5211684 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3311685
[email protected]dd3aa792013-07-16 19:10:2311686 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3311687}
11688
bncd16676a2016-07-20 16:23:0111689TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1511690 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5211691 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3611692 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4811693 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
11694 base::WriteFile(temp_file, temp_file_content.c_str(),
11695 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1111696 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3611697
danakj1fd259a02016-04-16 03:17:0911698 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911699 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411700 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0711701 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211702 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711703
11704 HttpRequestInfo request;
11705 request.method = "POST";
bncce36dca22015-04-21 22:11:2311706 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711707 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011708 request.traffic_annotation =
11709 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711710
[email protected]999dd8c2013-11-12 06:45:5411711 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0911712 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611713 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3611714
Ryan Sleevib8d7ea02018-05-07 20:01:0111715 StaticSocketDataProvider data;
[email protected]bb88e1d32013-05-03 23:11:0711716 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3611717
[email protected]49639fa2011-12-20 23:22:4111718 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3611719
tfarina42834112016-09-22 13:38:2011720 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111721 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3611722
11723 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111724 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3611725
[email protected]dd3aa792013-07-16 19:10:2311726 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3611727}
11728
bncd16676a2016-07-20 16:23:0111729TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0311730 class FakeUploadElementReader : public UploadElementReader {
11731 public:
Chris Watkins7a41d3552017-12-01 02:13:2711732 FakeUploadElementReader() = default;
11733 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0311734
Matt Menkecc1d3a902018-02-05 18:27:3311735 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0311736
11737 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3311738 int Init(CompletionOnceCallback callback) override {
11739 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0311740 return ERR_IO_PENDING;
11741 }
avibf0746c2015-12-09 19:53:1411742 uint64_t GetContentLength() const override { return 0; }
11743 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2011744 int Read(IOBuffer* buf,
11745 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3311746 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0311747 return ERR_FAILED;
11748 }
11749
11750 private:
Matt Menkecc1d3a902018-02-05 18:27:3311751 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0311752 };
11753
11754 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0911755 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11756 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2211757 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0311758
11759 HttpRequestInfo request;
11760 request.method = "POST";
bncce36dca22015-04-21 22:11:2311761 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0311762 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011763 request.traffic_annotation =
11764 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0311765
danakj1fd259a02016-04-16 03:17:0911766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811767 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911768 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0311769
11770 StaticSocketDataProvider data;
11771 session_deps_.socket_factory->AddSocketDataProvider(&data);
11772
11773 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2011774 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111775 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5511776 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0311777
11778 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3311779 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
11780 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0311781
11782 // Return Init()'s result after the transaction gets destroyed.
11783 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3311784 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0311785}
11786
[email protected]aeefc9e82010-02-19 16:18:2711787// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0111788TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2711789 HttpRequestInfo request;
11790 request.method = "GET";
bncce36dca22015-04-21 22:11:2311791 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011792 request.traffic_annotation =
11793 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2711794
11795 // First transaction will request a resource and receive a Basic challenge
11796 // with realm="first_realm".
11797 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311798 MockWrite(
11799 "GET / HTTP/1.1\r\n"
11800 "Host: www.example.org\r\n"
11801 "Connection: keep-alive\r\n"
11802 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711803 };
11804 MockRead data_reads1[] = {
11805 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11806 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11807 "\r\n"),
11808 };
11809
bnc691fda62016-08-12 00:43:1611810 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2711811 // for first_realm. The server will reject and provide a challenge with
11812 // second_realm.
11813 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311814 MockWrite(
11815 "GET / HTTP/1.1\r\n"
11816 "Host: www.example.org\r\n"
11817 "Connection: keep-alive\r\n"
11818 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
11819 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711820 };
11821 MockRead data_reads2[] = {
11822 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11823 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
11824 "\r\n"),
11825 };
11826
11827 // This again fails, and goes back to first_realm. Make sure that the
11828 // entry is removed from cache.
11829 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2311830 MockWrite(
11831 "GET / HTTP/1.1\r\n"
11832 "Host: www.example.org\r\n"
11833 "Connection: keep-alive\r\n"
11834 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
11835 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711836 };
11837 MockRead data_reads3[] = {
11838 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11839 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11840 "\r\n"),
11841 };
11842
11843 // Try one last time (with the correct password) and get the resource.
11844 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2311845 MockWrite(
11846 "GET / HTTP/1.1\r\n"
11847 "Host: www.example.org\r\n"
11848 "Connection: keep-alive\r\n"
11849 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
11850 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711851 };
11852 MockRead data_reads4[] = {
11853 MockRead("HTTP/1.1 200 OK\r\n"
11854 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5011855 "Content-Length: 5\r\n"
11856 "\r\n"
11857 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2711858 };
11859
Ryan Sleevib8d7ea02018-05-07 20:01:0111860 StaticSocketDataProvider data1(data_reads1, data_writes1);
11861 StaticSocketDataProvider data2(data_reads2, data_writes2);
11862 StaticSocketDataProvider data3(data_reads3, data_writes3);
11863 StaticSocketDataProvider data4(data_reads4, data_writes4);
[email protected]bb88e1d32013-05-03 23:11:0711864 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11865 session_deps_.socket_factory->AddSocketDataProvider(&data2);
11866 session_deps_.socket_factory->AddSocketDataProvider(&data3);
11867 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2711868
[email protected]49639fa2011-12-20 23:22:4111869 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2711870
danakj1fd259a02016-04-16 03:17:0911871 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611872 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011873
[email protected]aeefc9e82010-02-19 16:18:2711874 // Issue the first request with Authorize headers. There should be a
11875 // password prompt for first_realm waiting to be filled in after the
11876 // transaction completes.
tfarina42834112016-09-22 13:38:2011877 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111878 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711879 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111880 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611881 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211882 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811883 base::Optional<AuthChallengeInfo> challenge = response->auth_challenge;
wezca1070932016-05-26 20:30:5211884 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411885 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311886 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411887 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911888 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711889
11890 // Issue the second request with an incorrect password. There should be a
11891 // password prompt for second_realm waiting to be filled in after the
11892 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4111893 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1611894 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
11895 callback2.callback());
robpercival214763f2016-07-01 23:27:0111896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711897 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111898 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611899 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211900 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811901 challenge = response->auth_challenge;
wezca1070932016-05-26 20:30:5211902 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411903 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311904 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411905 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911906 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711907
11908 // Issue the third request with another incorrect password. There should be
11909 // a password prompt for first_realm waiting to be filled in. If the password
11910 // prompt is not present, it indicates that the HttpAuthCacheEntry for
11911 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4111912 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1611913 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
11914 callback3.callback());
robpercival214763f2016-07-01 23:27:0111915 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711916 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0111917 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611918 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211919 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811920 challenge = response->auth_challenge;
wezca1070932016-05-26 20:30:5211921 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411922 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311923 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411924 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911925 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711926
11927 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4111928 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1611929 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
11930 callback4.callback());
robpercival214763f2016-07-01 23:27:0111931 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711932 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0111933 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611934 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211935 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811936 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]aeefc9e82010-02-19 16:18:2711937}
11938
Bence Béky230ac612017-08-30 19:17:0811939// Regression test for https://crbug.com/754395.
11940TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
11941 MockRead data_reads[] = {
11942 MockRead("HTTP/1.1 200 OK\r\n"),
11943 MockRead(kAlternativeServiceHttpHeader),
11944 MockRead("\r\n"),
11945 MockRead("hello world"),
11946 MockRead(SYNCHRONOUS, OK),
11947 };
11948
11949 HttpRequestInfo request;
11950 request.method = "GET";
11951 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011952 request.traffic_annotation =
11953 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0811954
Ryan Sleevib8d7ea02018-05-07 20:01:0111955 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:0811956 session_deps_.socket_factory->AddSocketDataProvider(&data);
11957
11958 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911959 ssl.ssl_info.cert =
11960 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11961 ASSERT_TRUE(ssl.ssl_info.cert);
11962 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811963 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11964
11965 TestCompletionCallback callback;
11966
11967 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11968 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11969
11970 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11971 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11972
11973 url::SchemeHostPort test_server(request.url);
11974 HttpServerProperties* http_server_properties =
11975 session->http_server_properties();
11976 EXPECT_TRUE(
11977 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11978
11979 EXPECT_THAT(callback.WaitForResult(), IsOk());
11980
11981 const HttpResponseInfo* response = trans.GetResponseInfo();
11982 ASSERT_TRUE(response);
11983 ASSERT_TRUE(response->headers);
11984 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11985 EXPECT_FALSE(response->was_fetched_via_spdy);
11986 EXPECT_FALSE(response->was_alpn_negotiated);
11987
11988 std::string response_data;
11989 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11990 EXPECT_EQ("hello world", response_data);
11991
11992 EXPECT_TRUE(
11993 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11994}
11995
bncd16676a2016-07-20 16:23:0111996TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211997 MockRead data_reads[] = {
11998 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311999 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212000 MockRead("\r\n"),
12001 MockRead("hello world"),
12002 MockRead(SYNCHRONOUS, OK),
12003 };
12004
12005 HttpRequestInfo request;
12006 request.method = "GET";
bncb26024382016-06-29 02:39:4512007 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012008 request.traffic_annotation =
12009 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5212010
Ryan Sleevib8d7ea02018-05-07 20:01:0112011 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5212012 session_deps_.socket_factory->AddSocketDataProvider(&data);
12013
bncb26024382016-06-29 02:39:4512014 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912015 ssl.ssl_info.cert =
12016 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12017 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512018 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12019
bncc958faa2015-07-31 18:14:5212020 TestCompletionCallback callback;
12021
danakj1fd259a02016-04-16 03:17:0912022 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612023 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5212024
tfarina42834112016-09-22 13:38:2012025 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112026 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5212027
bncb26024382016-06-29 02:39:4512028 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4012029 HttpServerProperties* http_server_properties =
12030 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412031 EXPECT_TRUE(
12032 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5212033
robpercival214763f2016-07-01 23:27:0112034 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5212035
bnc691fda62016-08-12 00:43:1612036 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212037 ASSERT_TRUE(response);
12038 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5212039 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12040 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212041 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212042
12043 std::string response_data;
bnc691fda62016-08-12 00:43:1612044 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212045 EXPECT_EQ("hello world", response_data);
12046
zhongyic4de03032017-05-19 04:07:3412047 AlternativeServiceInfoVector alternative_service_info_vector =
12048 http_server_properties->GetAlternativeServiceInfos(test_server);
12049 ASSERT_EQ(1u, alternative_service_info_vector.size());
12050 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
12051 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412052 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5212053}
12054
bnce3dd56f2016-06-01 10:37:1112055// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0112056TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112057 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1112058 MockRead data_reads[] = {
12059 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312060 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1112061 MockRead("\r\n"),
12062 MockRead("hello world"),
12063 MockRead(SYNCHRONOUS, OK),
12064 };
12065
12066 HttpRequestInfo request;
12067 request.method = "GET";
12068 request.url = GURL("http://www.example.org/");
12069 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012070 request.traffic_annotation =
12071 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112072
Ryan Sleevib8d7ea02018-05-07 20:01:0112073 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112074 session_deps_.socket_factory->AddSocketDataProvider(&data);
12075
12076 TestCompletionCallback callback;
12077
12078 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612079 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112080
12081 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4012082 HttpServerProperties* http_server_properties =
12083 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412084 EXPECT_TRUE(
12085 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112086
tfarina42834112016-09-22 13:38:2012087 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112088 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12089 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1112090
bnc691fda62016-08-12 00:43:1612091 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1112092 ASSERT_TRUE(response);
12093 ASSERT_TRUE(response->headers);
12094 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12095 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212096 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1112097
12098 std::string response_data;
bnc691fda62016-08-12 00:43:1612099 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1112100 EXPECT_EQ("hello world", response_data);
12101
zhongyic4de03032017-05-19 04:07:3412102 EXPECT_TRUE(
12103 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112104}
12105
bnca86731e2017-04-17 12:31:2812106// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2512107// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0112108TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2512109 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2812110 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4512111
bnc8bef8da22016-05-30 01:28:2512112 HttpRequestInfo request;
12113 request.method = "GET";
bncb26024382016-06-29 02:39:4512114 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2512115 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012116 request.traffic_annotation =
12117 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2512118
12119 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12120 StaticSocketDataProvider first_data;
12121 first_data.set_connect_data(mock_connect);
12122 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512123 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612124 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512125 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2512126
12127 MockRead data_reads[] = {
12128 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12129 MockRead(ASYNC, OK),
12130 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112131 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnc8bef8da22016-05-30 01:28:2512132 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12133
12134 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12135
bnc525e175a2016-06-20 12:36:4012136 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2512137 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112138 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
12139 444);
bnc8bef8da22016-05-30 01:28:2512140 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112141 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2512142 url::SchemeHostPort(request.url), alternative_service, expiration);
12143
bnc691fda62016-08-12 00:43:1612144 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2512145 TestCompletionCallback callback;
12146
tfarina42834112016-09-22 13:38:2012147 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2512148 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112149 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2512150}
12151
bnce3dd56f2016-06-01 10:37:1112152// Regression test for https://crbug.com/615497:
12153// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0112154TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112155 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1112156 HttpRequestInfo request;
12157 request.method = "GET";
12158 request.url = GURL("http://www.example.org/");
12159 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012160 request.traffic_annotation =
12161 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112162
12163 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12164 StaticSocketDataProvider first_data;
12165 first_data.set_connect_data(mock_connect);
12166 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
12167
12168 MockRead data_reads[] = {
12169 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12170 MockRead(ASYNC, OK),
12171 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112172 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112173 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12174
12175 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12176
bnc525e175a2016-06-20 12:36:4012177 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1112178 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112179 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1112180 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112181 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1112182 url::SchemeHostPort(request.url), alternative_service, expiration);
12183
bnc691fda62016-08-12 00:43:1612184 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112185 TestCompletionCallback callback;
12186
tfarina42834112016-09-22 13:38:2012187 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1112188 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112189 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1112190}
12191
bncd16676a2016-07-20 16:23:0112192TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0812193 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0912194 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012195 HttpServerProperties* http_server_properties =
12196 session->http_server_properties();
bncb26024382016-06-29 02:39:4512197 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2112198 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0812199 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112200 http_server_properties->SetQuicAlternativeService(
12201 test_server, alternative_service, expiration,
12202 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3412203 EXPECT_EQ(
12204 1u,
12205 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0812206
12207 // Send a clear header.
12208 MockRead data_reads[] = {
12209 MockRead("HTTP/1.1 200 OK\r\n"),
12210 MockRead("Alt-Svc: clear\r\n"),
12211 MockRead("\r\n"),
12212 MockRead("hello world"),
12213 MockRead(SYNCHRONOUS, OK),
12214 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112215 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnc4f575852015-10-14 18:35:0812216 session_deps_.socket_factory->AddSocketDataProvider(&data);
12217
bncb26024382016-06-29 02:39:4512218 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912219 ssl.ssl_info.cert =
12220 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12221 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512222 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12223
bnc4f575852015-10-14 18:35:0812224 HttpRequestInfo request;
12225 request.method = "GET";
bncb26024382016-06-29 02:39:4512226 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012227 request.traffic_annotation =
12228 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0812229
12230 TestCompletionCallback callback;
12231
bnc691fda62016-08-12 00:43:1612232 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0812233
tfarina42834112016-09-22 13:38:2012234 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112235 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0812236
bnc691fda62016-08-12 00:43:1612237 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212238 ASSERT_TRUE(response);
12239 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0812240 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12241 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212242 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0812243
12244 std::string response_data;
bnc691fda62016-08-12 00:43:1612245 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0812246 EXPECT_EQ("hello world", response_data);
12247
zhongyic4de03032017-05-19 04:07:3412248 EXPECT_TRUE(
12249 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0812250}
12251
bncd16676a2016-07-20 16:23:0112252TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5212253 MockRead data_reads[] = {
12254 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312255 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
12256 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5212257 MockRead("hello world"),
12258 MockRead(SYNCHRONOUS, OK),
12259 };
12260
12261 HttpRequestInfo request;
12262 request.method = "GET";
bncb26024382016-06-29 02:39:4512263 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012264 request.traffic_annotation =
12265 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5212266
Ryan Sleevib8d7ea02018-05-07 20:01:0112267 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5212268 session_deps_.socket_factory->AddSocketDataProvider(&data);
12269
bncb26024382016-06-29 02:39:4512270 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912271 ssl.ssl_info.cert =
12272 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12273 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512274 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12275
bncc958faa2015-07-31 18:14:5212276 TestCompletionCallback callback;
12277
danakj1fd259a02016-04-16 03:17:0912278 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612279 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5212280
tfarina42834112016-09-22 13:38:2012281 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112282 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5212283
bncb26024382016-06-29 02:39:4512284 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4012285 HttpServerProperties* http_server_properties =
12286 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412287 EXPECT_TRUE(
12288 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5212289
robpercival214763f2016-07-01 23:27:0112290 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5212291
bnc691fda62016-08-12 00:43:1612292 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212293 ASSERT_TRUE(response);
12294 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5212295 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12296 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212297 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212298
12299 std::string response_data;
bnc691fda62016-08-12 00:43:1612300 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212301 EXPECT_EQ("hello world", response_data);
12302
zhongyic4de03032017-05-19 04:07:3412303 AlternativeServiceInfoVector alternative_service_info_vector =
12304 http_server_properties->GetAlternativeServiceInfos(test_server);
12305 ASSERT_EQ(2u, alternative_service_info_vector.size());
12306
12307 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
12308 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412309 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412310 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
12311 1234);
12312 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5412313 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5212314}
12315
bncd16676a2016-07-20 16:23:0112316TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612317 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212318 HostPortPair alternative("alternative.example.org", 443);
12319 std::string origin_url = "https://origin.example.org:443";
12320 std::string alternative_url = "https://alternative.example.org:443";
12321
12322 // Negotiate HTTP/1.1 with alternative.example.org.
12323 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612324 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212325 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12326
12327 // HTTP/1.1 data for request.
12328 MockWrite http_writes[] = {
12329 MockWrite("GET / HTTP/1.1\r\n"
12330 "Host: alternative.example.org\r\n"
12331 "Connection: keep-alive\r\n\r\n"),
12332 };
12333
12334 MockRead http_reads[] = {
12335 MockRead("HTTP/1.1 200 OK\r\n"
12336 "Content-Type: text/html; charset=iso-8859-1\r\n"
12337 "Content-Length: 40\r\n\r\n"
12338 "first HTTP/1.1 response from alternative"),
12339 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112340 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212341 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12342
12343 StaticSocketDataProvider data_refused;
12344 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12345 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12346
zhongyi3d4a55e72016-04-22 20:36:4612347 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0912348 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012349 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212350 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112351 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0212352 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112353 http_server_properties->SetQuicAlternativeService(
12354 server, alternative_service, expiration,
12355 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0212356 // Mark the QUIC alternative service as broken.
12357 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
12358
zhongyi48704c182015-12-07 07:52:0212359 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612360 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212361 request.method = "GET";
12362 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1012363 request.traffic_annotation =
12364 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12365
zhongyi48704c182015-12-07 07:52:0212366 TestCompletionCallback callback;
12367 NetErrorDetails details;
12368 EXPECT_FALSE(details.quic_broken);
12369
tfarina42834112016-09-22 13:38:2012370 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612371 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212372 EXPECT_TRUE(details.quic_broken);
12373}
12374
bncd16676a2016-07-20 16:23:0112375TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612376 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212377 HostPortPair alternative1("alternative1.example.org", 443);
12378 HostPortPair alternative2("alternative2.example.org", 443);
12379 std::string origin_url = "https://origin.example.org:443";
12380 std::string alternative_url1 = "https://alternative1.example.org:443";
12381 std::string alternative_url2 = "https://alternative2.example.org:443";
12382
12383 // Negotiate HTTP/1.1 with alternative1.example.org.
12384 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612385 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212386 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12387
12388 // HTTP/1.1 data for request.
12389 MockWrite http_writes[] = {
12390 MockWrite("GET / HTTP/1.1\r\n"
12391 "Host: alternative1.example.org\r\n"
12392 "Connection: keep-alive\r\n\r\n"),
12393 };
12394
12395 MockRead http_reads[] = {
12396 MockRead("HTTP/1.1 200 OK\r\n"
12397 "Content-Type: text/html; charset=iso-8859-1\r\n"
12398 "Content-Length: 40\r\n\r\n"
12399 "first HTTP/1.1 response from alternative1"),
12400 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112401 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212402 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12403
12404 StaticSocketDataProvider data_refused;
12405 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12406 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12407
danakj1fd259a02016-04-16 03:17:0912408 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012409 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212410 session->http_server_properties();
12411
zhongyi3d4a55e72016-04-22 20:36:4612412 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0212413 AlternativeServiceInfoVector alternative_service_info_vector;
12414 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
12415
bnc3472afd2016-11-17 15:27:2112416 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2112417 alternative_service_info_vector.push_back(
12418 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12419 alternative_service1, expiration,
12420 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2112421 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2112422 alternative_service_info_vector.push_back(
12423 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12424 alternative_service2, expiration,
12425 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0212426
12427 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4612428 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0212429
12430 // Mark one of the QUIC alternative service as broken.
12431 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3412432 EXPECT_EQ(2u,
12433 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0212434
zhongyi48704c182015-12-07 07:52:0212435 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612436 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212437 request.method = "GET";
12438 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1012439 request.traffic_annotation =
12440 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12441
zhongyi48704c182015-12-07 07:52:0212442 TestCompletionCallback callback;
12443 NetErrorDetails details;
12444 EXPECT_FALSE(details.quic_broken);
12445
tfarina42834112016-09-22 13:38:2012446 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612447 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212448 EXPECT_FALSE(details.quic_broken);
12449}
12450
bncd16676a2016-07-20 16:23:0112451TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4212452 HttpRequestInfo request;
12453 request.method = "GET";
bncb26024382016-06-29 02:39:4512454 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012455 request.traffic_annotation =
12456 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4212457
[email protected]d973e99a2012-02-17 21:02:3612458 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4212459 StaticSocketDataProvider first_data;
12460 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712461 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512462 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612463 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512464 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4212465
12466 MockRead data_reads[] = {
12467 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12468 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612469 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4212470 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112471 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712472 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4212473
danakj1fd259a02016-04-16 03:17:0912474 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4212475
bnc525e175a2016-06-20 12:36:4012476 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312477 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4612478 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1112479 // Port must be < 1024, or the header will be ignored (since initial port was
12480 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2112481 // Port is ignored by MockConnect anyway.
12482 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12483 666);
bnc7dc7e1b42015-07-28 14:43:1212484 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112485 http_server_properties->SetHttp2AlternativeService(
12486 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4212487
bnc691fda62016-08-12 00:43:1612488 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112489 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4212490
tfarina42834112016-09-22 13:38:2012491 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112492 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12493 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4212494
bnc691fda62016-08-12 00:43:1612495 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212496 ASSERT_TRUE(response);
12497 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4212498 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12499
12500 std::string response_data;
bnc691fda62016-08-12 00:43:1612501 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4212502 EXPECT_EQ("hello world", response_data);
12503
zhongyic4de03032017-05-19 04:07:3412504 const AlternativeServiceInfoVector alternative_service_info_vector =
12505 http_server_properties->GetAlternativeServiceInfos(server);
12506 ASSERT_EQ(1u, alternative_service_info_vector.size());
12507 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412508 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412509 EXPECT_TRUE(
12510 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4212511}
12512
bnc55ff9da2015-08-19 18:42:3512513// Ensure that we are not allowed to redirect traffic via an alternate protocol
12514// to an unrestricted (port >= 1024) when the original traffic was on a
12515// restricted port (port < 1024). Ensure that we can redirect in all other
12516// cases.
bncd16676a2016-07-20 16:23:0112517TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1112518 HttpRequestInfo restricted_port_request;
12519 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512520 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112521 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012522 restricted_port_request.traffic_annotation =
12523 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112524
[email protected]d973e99a2012-02-17 21:02:3612525 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112526 StaticSocketDataProvider first_data;
12527 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712528 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112529
12530 MockRead data_reads[] = {
12531 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12532 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612533 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112534 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112535 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712536 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512537 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612538 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512539 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112540
danakj1fd259a02016-04-16 03:17:0912541 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112542
bnc525e175a2016-06-20 12:36:4012543 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312544 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112545 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112546 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12547 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212548 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112549 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612550 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012551 expiration);
[email protected]3912662a32011-10-04 00:51:1112552
bnc691fda62016-08-12 00:43:1612553 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112554 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112555
tfarina42834112016-09-22 13:38:2012556 int rv = trans.Start(&restricted_port_request, callback.callback(),
12557 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112558 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112559 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0112560 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1912561}
[email protected]3912662a32011-10-04 00:51:1112562
bnc55ff9da2015-08-19 18:42:3512563// Ensure that we are allowed to redirect traffic via an alternate protocol to
12564// an unrestricted (port >= 1024) when the original traffic was on a restricted
12565// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0112566TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0712567 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1912568
12569 HttpRequestInfo restricted_port_request;
12570 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512571 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1912572 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012573 restricted_port_request.traffic_annotation =
12574 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1912575
12576 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12577 StaticSocketDataProvider first_data;
12578 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712579 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1912580
12581 MockRead data_reads[] = {
12582 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12583 MockRead("hello world"),
12584 MockRead(ASYNC, OK),
12585 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112586 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712587 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512588 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612589 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512590 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1912591
danakj1fd259a02016-04-16 03:17:0912592 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1912593
bnc525e175a2016-06-20 12:36:4012594 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1912595 session->http_server_properties();
12596 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112597 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12598 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212599 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112600 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612601 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012602 expiration);
[email protected]c54c6962013-02-01 04:53:1912603
bnc691fda62016-08-12 00:43:1612604 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1912605 TestCompletionCallback callback;
12606
tfarina42834112016-09-22 13:38:2012607 EXPECT_EQ(ERR_IO_PENDING,
12608 trans.Start(&restricted_port_request, callback.callback(),
12609 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1912610 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0112611 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112612}
12613
bnc55ff9da2015-08-19 18:42:3512614// Ensure that we are not allowed to redirect traffic via an alternate protocol
12615// to an unrestricted (port >= 1024) when the original traffic was on a
12616// restricted port (port < 1024). Ensure that we can redirect in all other
12617// cases.
bncd16676a2016-07-20 16:23:0112618TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1112619 HttpRequestInfo restricted_port_request;
12620 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512621 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112622 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012623 restricted_port_request.traffic_annotation =
12624 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112625
[email protected]d973e99a2012-02-17 21:02:3612626 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112627 StaticSocketDataProvider first_data;
12628 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712629 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112630
12631 MockRead data_reads[] = {
12632 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12633 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612634 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112635 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112636 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712637 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112638
bncb26024382016-06-29 02:39:4512639 SSLSocketDataProvider ssl(ASYNC, OK);
12640 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12641
danakj1fd259a02016-04-16 03:17:0912642 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112643
bnc525e175a2016-06-20 12:36:4012644 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312645 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112646 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112647 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12648 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212649 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112650 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612651 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012652 expiration);
[email protected]3912662a32011-10-04 00:51:1112653
bnc691fda62016-08-12 00:43:1612654 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112655 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112656
tfarina42834112016-09-22 13:38:2012657 int rv = trans.Start(&restricted_port_request, callback.callback(),
12658 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112659 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112660 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112661 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112662}
12663
bnc55ff9da2015-08-19 18:42:3512664// Ensure that we are not allowed to redirect traffic via an alternate protocol
12665// to an unrestricted (port >= 1024) when the original traffic was on a
12666// restricted port (port < 1024). Ensure that we can redirect in all other
12667// cases.
bncd16676a2016-07-20 16:23:0112668TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1112669 HttpRequestInfo unrestricted_port_request;
12670 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512671 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112672 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012673 unrestricted_port_request.traffic_annotation =
12674 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112675
[email protected]d973e99a2012-02-17 21:02:3612676 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112677 StaticSocketDataProvider first_data;
12678 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712679 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112680
12681 MockRead data_reads[] = {
12682 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12683 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612684 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112685 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112686 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712687 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512688 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612689 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512690 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112691
danakj1fd259a02016-04-16 03:17:0912692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112693
bnc525e175a2016-06-20 12:36:4012694 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312695 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112696 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112697 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12698 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212699 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112700 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612701 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012702 expiration);
[email protected]3912662a32011-10-04 00:51:1112703
bnc691fda62016-08-12 00:43:1612704 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112705 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112706
bnc691fda62016-08-12 00:43:1612707 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012708 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112709 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112710 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112711 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112712}
12713
bnc55ff9da2015-08-19 18:42:3512714// Ensure that we are not allowed to redirect traffic via an alternate protocol
12715// to an unrestricted (port >= 1024) when the original traffic was on a
12716// restricted port (port < 1024). Ensure that we can redirect in all other
12717// cases.
bncd16676a2016-07-20 16:23:0112718TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1112719 HttpRequestInfo unrestricted_port_request;
12720 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512721 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112722 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012723 unrestricted_port_request.traffic_annotation =
12724 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112725
[email protected]d973e99a2012-02-17 21:02:3612726 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112727 StaticSocketDataProvider first_data;
12728 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712729 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112730
12731 MockRead data_reads[] = {
12732 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12733 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612734 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112735 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112736 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712737 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112738
bncb26024382016-06-29 02:39:4512739 SSLSocketDataProvider ssl(ASYNC, OK);
12740 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12741
danakj1fd259a02016-04-16 03:17:0912742 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112743
bnc525e175a2016-06-20 12:36:4012744 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312745 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2212746 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2112747 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12748 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212749 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112750 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612751 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012752 expiration);
[email protected]3912662a32011-10-04 00:51:1112753
bnc691fda62016-08-12 00:43:1612754 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112755 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112756
bnc691fda62016-08-12 00:43:1612757 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012758 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112759 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112760 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0112761 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112762}
12763
bnc55ff9da2015-08-19 18:42:3512764// Ensure that we are not allowed to redirect traffic via an alternate protocol
Xida Chen9bfe0b62018-04-24 19:52:2112765// to an unsafe port, and that we resume the second HttpStreamFactory::Job once
12766// the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0112767TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0212768 HttpRequestInfo request;
12769 request.method = "GET";
bncce36dca22015-04-21 22:11:2312770 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012771 request.traffic_annotation =
12772 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0212773
12774 // The alternate protocol request will error out before we attempt to connect,
12775 // so only the standard HTTP request will try to connect.
12776 MockRead data_reads[] = {
12777 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12778 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612779 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0212780 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112781 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712782 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0212783
danakj1fd259a02016-04-16 03:17:0912784 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0212785
bnc525e175a2016-06-20 12:36:4012786 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0212787 session->http_server_properties();
12788 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2112789 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12790 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1212791 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112792 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612793 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0212794
bnc691fda62016-08-12 00:43:1612795 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0212796 TestCompletionCallback callback;
12797
tfarina42834112016-09-22 13:38:2012798 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0212800 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0112801 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212802
bnc691fda62016-08-12 00:43:1612803 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212804 ASSERT_TRUE(response);
12805 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0212806 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12807
12808 std::string response_data;
bnc691fda62016-08-12 00:43:1612809 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212810 EXPECT_EQ("hello world", response_data);
12811}
12812
bncd16676a2016-07-20 16:23:0112813TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5412814 HttpRequestInfo request;
12815 request.method = "GET";
bncb26024382016-06-29 02:39:4512816 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012817 request.traffic_annotation =
12818 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412819
12820 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212821 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312822 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212823 MockRead("\r\n"),
12824 MockRead("hello world"),
12825 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12826 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5412827
Ryan Sleevib8d7ea02018-05-07 20:01:0112828 StaticSocketDataProvider first_transaction(data_reads,
12829 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712830 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512831 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612832 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512833 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412834
bnc032658ba2016-09-26 18:17:1512835 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412836
Ryan Hamilton0239aac2018-05-19 00:03:1312837 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512838 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112839 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412840
Raul Tambre94493c652019-03-11 17:18:3512841 spdy::SpdySerializedFrame resp(
12842 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1312843 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412844 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112845 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412846 };
12847
Ryan Sleevib8d7ea02018-05-07 20:01:0112848 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712849 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412850
[email protected]d973e99a2012-02-17 21:02:3612851 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112852 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512853 hanging_non_alternate_protocol_socket.set_connect_data(
12854 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712855 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512856 &hanging_non_alternate_protocol_socket);
12857
[email protected]49639fa2011-12-20 23:22:4112858 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412859
danakj1fd259a02016-04-16 03:17:0912860 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812861 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912862 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412863
tfarina42834112016-09-22 13:38:2012864 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112865 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12866 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412867
12868 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212869 ASSERT_TRUE(response);
12870 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412871 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12872
12873 std::string response_data;
robpercival214763f2016-07-01 23:27:0112874 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412875 EXPECT_EQ("hello world", response_data);
12876
bnc87dcefc2017-05-25 12:47:5812877 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912878 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412879
tfarina42834112016-09-22 13:38:2012880 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12882 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412883
12884 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212885 ASSERT_TRUE(response);
12886 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212887 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312888 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212889 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412890
robpercival214763f2016-07-01 23:27:0112891 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412892 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5412893}
12894
bncd16676a2016-07-20 16:23:0112895TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5512896 HttpRequestInfo request;
12897 request.method = "GET";
bncb26024382016-06-29 02:39:4512898 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012899 request.traffic_annotation =
12900 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512901
bncb26024382016-06-29 02:39:4512902 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5512903 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212904 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312905 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212906 MockRead("\r\n"),
12907 MockRead("hello world"),
12908 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12909 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512910 };
12911
Ryan Sleevib8d7ea02018-05-07 20:01:0112912 StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
bncb26024382016-06-29 02:39:4512913 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5512914
bncb26024382016-06-29 02:39:4512915 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912916 ssl_http11.ssl_info.cert =
12917 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12918 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4512919 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
12920
12921 // Second transaction starts an alternative and a non-alternative Job.
12922 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3612923 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112924 StaticSocketDataProvider hanging_socket1;
mmenkecc2298e2015-12-07 18:20:1812925 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1812926 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
12927
Ryan Sleevib8d7ea02018-05-07 20:01:0112928 StaticSocketDataProvider hanging_socket2;
mmenkecc2298e2015-12-07 18:20:1812929 hanging_socket2.set_connect_data(never_finishing_connect);
12930 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5512931
bncb26024382016-06-29 02:39:4512932 // Third transaction starts an alternative and a non-alternative job.
12933 // The non-alternative job hangs, but the alternative one succeeds.
12934 // The second transaction, still pending, binds to this socket.
Ryan Hamilton0239aac2018-05-19 00:03:1312935 spdy::SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4512936 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1312937 spdy::SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4512938 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5512939 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112940 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5512941 };
Raul Tambre94493c652019-03-11 17:18:3512942 spdy::SpdySerializedFrame resp1(
12943 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1312944 spdy::SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
Raul Tambre94493c652019-03-11 17:18:3512945 spdy::SpdySerializedFrame resp2(
12946 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1312947 spdy::SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5512948 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112949 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
12950 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1312951 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5512952 };
12953
Ryan Sleevib8d7ea02018-05-07 20:01:0112954 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712955 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5512956
bnc032658ba2016-09-26 18:17:1512957 AddSSLSocketData();
bncb26024382016-06-29 02:39:4512958
Ryan Sleevib8d7ea02018-05-07 20:01:0112959 StaticSocketDataProvider hanging_socket3;
mmenkecc2298e2015-12-07 18:20:1812960 hanging_socket3.set_connect_data(never_finishing_connect);
12961 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512962
danakj1fd259a02016-04-16 03:17:0912963 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112964 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012965 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512966
tfarina42834112016-09-22 13:38:2012967 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112968 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12969 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512970
12971 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212972 ASSERT_TRUE(response);
12973 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512974 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12975
12976 std::string response_data;
robpercival214763f2016-07-01 23:27:0112977 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512978 EXPECT_EQ("hello world", response_data);
12979
[email protected]49639fa2011-12-20 23:22:4112980 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012981 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012982 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512984
[email protected]49639fa2011-12-20 23:22:4112985 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012986 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012987 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112988 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512989
robpercival214763f2016-07-01 23:27:0112990 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12991 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512992
12993 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212994 ASSERT_TRUE(response);
12995 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212996 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512997 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212998 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112999 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513000 EXPECT_EQ("hello!", response_data);
13001
13002 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5213003 ASSERT_TRUE(response);
13004 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213005 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5513006 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213007 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113008 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513009 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5513010}
13011
bncd16676a2016-07-20 16:23:0113012TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
Bence Békybcae37092018-06-12 04:18:5313013 session_deps_.host_resolver->set_synchronous_mode(true);
13014
[email protected]2d6728692011-03-12 01:39:5513015 HttpRequestInfo request;
13016 request.method = "GET";
bncb26024382016-06-29 02:39:4513017 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013018 request.traffic_annotation =
13019 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5513020
13021 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213022 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313023 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213024 MockRead("\r\n"),
13025 MockRead("hello world"),
13026 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13027 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5513028 };
13029
Ryan Sleevib8d7ea02018-05-07 20:01:0113030 StaticSocketDataProvider first_transaction(data_reads,
13031 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713032 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5513033
[email protected]8ddf8322012-02-23 18:08:0613034 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4913035 ssl.ssl_info.cert =
13036 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
13037 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0713038 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5513039
[email protected]d973e99a2012-02-17 21:02:3613040 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113041 StaticSocketDataProvider hanging_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513042 hanging_alternate_protocol_socket.set_connect_data(
13043 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713044 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513045 &hanging_alternate_protocol_socket);
13046
bncb26024382016-06-29 02:39:4513047 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
Ryan Sleevib8d7ea02018-05-07 20:01:0113048 StaticSocketDataProvider second_transaction(data_reads,
13049 base::span<MockWrite>());
mmenkecc2298e2015-12-07 18:20:1813050 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4513051 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5513052
[email protected]49639fa2011-12-20 23:22:4113053 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5513054
danakj1fd259a02016-04-16 03:17:0913055 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813056 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913057 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5513058
tfarina42834112016-09-22 13:38:2013059 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113060 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13061 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513062
13063 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213064 ASSERT_TRUE(response);
13065 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513066 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13067
13068 std::string response_data;
robpercival214763f2016-07-01 23:27:0113069 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513070 EXPECT_EQ("hello world", response_data);
13071
bnc87dcefc2017-05-25 12:47:5813072 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913073 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5513074
tfarina42834112016-09-22 13:38:2013075 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113076 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13077 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513078
13079 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213080 ASSERT_TRUE(response);
13081 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513082 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13083 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213084 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5513085
robpercival214763f2016-07-01 23:27:0113086 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513087 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5513088}
13089
bnc2e884782016-08-11 19:45:1913090// Test that proxy is resolved using the origin url,
13091// regardless of the alternative server.
13092TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
13093 // Configure proxy to bypass www.example.org, which is the origin URL.
13094 ProxyConfig proxy_config;
13095 proxy_config.proxy_rules().ParseFromString("myproxy:70");
13096 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4913097 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
13098 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1913099
13100 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1913101 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1913102 &capturing_proxy_resolver);
13103
13104 TestNetLog net_log;
13105
Bence Béky53a5aef2018-03-29 21:54:1213106 session_deps_.proxy_resolution_service =
13107 std::make_unique<ProxyResolutionService>(
13108 std::move(proxy_config_service), std::move(proxy_resolver_factory),
13109 &net_log);
bnc2e884782016-08-11 19:45:1913110
13111 session_deps_.net_log = &net_log;
13112
13113 // Configure alternative service with a hostname that is not bypassed by the
13114 // proxy.
13115 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13116 HttpServerProperties* http_server_properties =
13117 session->http_server_properties();
13118 url::SchemeHostPort server("https", "www.example.org", 443);
13119 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2113120 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1913121 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2113122 http_server_properties->SetHttp2AlternativeService(
13123 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1913124
13125 // Non-alternative job should hang.
13126 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113127 StaticSocketDataProvider hanging_alternate_protocol_socket;
bnc2e884782016-08-11 19:45:1913128 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
13129 session_deps_.socket_factory->AddSocketDataProvider(
13130 &hanging_alternate_protocol_socket);
13131
bnc032658ba2016-09-26 18:17:1513132 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1913133
13134 HttpRequestInfo request;
13135 request.method = "GET";
13136 request.url = GURL("https://www.example.org/");
13137 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1013138 request.traffic_annotation =
13139 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1913140
Ryan Hamilton0239aac2018-05-19 00:03:1313141 spdy::SpdySerializedFrame req(
bnc2e884782016-08-11 19:45:1913142 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
13143
13144 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
13145
Ryan Hamilton0239aac2018-05-19 00:03:1313146 spdy::SpdySerializedFrame resp(
13147 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13148 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc2e884782016-08-11 19:45:1913149 MockRead spdy_reads[] = {
13150 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
13151 };
13152
Ryan Sleevib8d7ea02018-05-07 20:01:0113153 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
bnc2e884782016-08-11 19:45:1913154 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
13155
13156 TestCompletionCallback callback;
13157
13158 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13159
tfarina42834112016-09-22 13:38:2013160 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1913161 EXPECT_THAT(callback.GetResult(rv), IsOk());
13162
13163 const HttpResponseInfo* response = trans.GetResponseInfo();
13164 ASSERT_TRUE(response);
13165 ASSERT_TRUE(response->headers);
13166 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13167 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213168 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1913169
13170 std::string response_data;
13171 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13172 EXPECT_EQ("hello!", response_data);
13173
13174 // Origin host bypasses proxy, no resolution should have happened.
13175 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
13176}
13177
bncd16676a2016-07-20 16:23:0113178TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1113179 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4213180 proxy_config.set_auto_detect(true);
13181 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1113182
sammc5dd160c2015-04-02 02:43:1313183 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4913184 session_deps_.proxy_resolution_service =
13185 std::make_unique<ProxyResolutionService>(
13186 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
13187 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
13188 std::make_unique<CapturingProxyResolverFactory>(
13189 &capturing_proxy_resolver),
13190 nullptr);
vishal.b62985ca92015-04-17 08:45:5113191 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0713192 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1113193
13194 HttpRequestInfo request;
13195 request.method = "GET";
bncb26024382016-06-29 02:39:4513196 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013197 request.traffic_annotation =
13198 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1113199
13200 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213201 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313202 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213203 MockRead("\r\n"),
13204 MockRead("hello world"),
13205 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13206 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1113207 };
13208
Ryan Sleevib8d7ea02018-05-07 20:01:0113209 StaticSocketDataProvider first_transaction(data_reads,
13210 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713211 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513212 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613213 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513214 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1113215
bnc032658ba2016-09-26 18:17:1513216 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1113217
Ryan Hamilton0239aac2018-05-19 00:03:1313218 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513219 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1113220 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313221 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2513222 "CONNECT www.example.org:443 HTTP/1.1\r\n"
13223 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1313224 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4113225 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1113226 };
13227
[email protected]d911f1b2010-05-05 22:39:4213228 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
13229
Raul Tambre94493c652019-03-11 17:18:3513230 spdy::SpdySerializedFrame resp(
13231 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1313232 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1113233 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113234 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
13235 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1113236 };
13237
Ryan Sleevib8d7ea02018-05-07 20:01:0113238 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713239 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1113240
[email protected]d973e99a2012-02-17 21:02:3613241 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113242 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513243 hanging_non_alternate_protocol_socket.set_connect_data(
13244 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713245 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513246 &hanging_non_alternate_protocol_socket);
13247
[email protected]49639fa2011-12-20 23:22:4113248 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1113249
danakj1fd259a02016-04-16 03:17:0913250 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813251 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913252 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113253
tfarina42834112016-09-22 13:38:2013254 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4113255 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13256 EXPECT_THAT(callback.WaitForResult(), IsOk());
13257
13258 const HttpResponseInfo* response = trans->GetResponseInfo();
13259 ASSERT_TRUE(response);
13260 ASSERT_TRUE(response->headers);
13261 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
13262 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213263 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4113264
13265 std::string response_data;
13266 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
13267 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1113268
bnc87dcefc2017-05-25 12:47:5813269 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913270 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113271
tfarina42834112016-09-22 13:38:2013272 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113273 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13274 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1113275
mmenkea2dcd3bf2016-08-16 21:49:4113276 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213277 ASSERT_TRUE(response);
13278 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213279 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313280 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213281 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1113282
robpercival214763f2016-07-01 23:27:0113283 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1113284 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4513285 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
13286 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313287 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2313288 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313289 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1113290
[email protected]029c83b62013-01-24 05:28:2013291 LoadTimingInfo load_timing_info;
13292 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
13293 TestLoadTimingNotReusedWithPac(load_timing_info,
13294 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1113295}
[email protected]631f1322010-04-30 17:59:1113296
bncd16676a2016-07-20 16:23:0113297TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4813298 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5413299 HttpRequestInfo request;
13300 request.method = "GET";
bncb26024382016-06-29 02:39:4513301 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013302 request.traffic_annotation =
13303 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5413304
13305 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213306 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313307 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213308 MockRead("\r\n"),
13309 MockRead("hello world"),
13310 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5413311 };
13312
Ryan Sleevib8d7ea02018-05-07 20:01:0113313 StaticSocketDataProvider first_transaction(data_reads,
13314 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713315 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513316 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613317 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513318 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5413319
bnc032658ba2016-09-26 18:17:1513320 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5413321
Ryan Hamilton0239aac2018-05-19 00:03:1313322 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513323 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113324 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5413325
Raul Tambre94493c652019-03-11 17:18:3513326 spdy::SpdySerializedFrame resp(
13327 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1313328 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5413329 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113330 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5413331 };
13332
Ryan Sleevib8d7ea02018-05-07 20:01:0113333 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713334 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5413335
[email protected]83039bb2011-12-09 18:43:5513336 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5413337
danakj1fd259a02016-04-16 03:17:0913338 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5413339
bnc87dcefc2017-05-25 12:47:5813340 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913341 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413342
tfarina42834112016-09-22 13:38:2013343 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113344 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13345 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413346
13347 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213348 ASSERT_TRUE(response);
13349 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5413350 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13351
13352 std::string response_data;
robpercival214763f2016-07-01 23:27:0113353 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413354 EXPECT_EQ("hello world", response_data);
13355
13356 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2513357 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013358 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1113359 PRIVACY_MODE_DISABLED,
13360 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2713361 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213362 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3813363
bnc87dcefc2017-05-25 12:47:5813364 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913365 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413366
tfarina42834112016-09-22 13:38:2013367 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113368 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13369 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413370
13371 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213372 ASSERT_TRUE(response);
13373 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213374 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313375 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213376 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5413377
robpercival214763f2016-07-01 23:27:0113378 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413379 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4213380}
13381
[email protected]044de0642010-06-17 10:42:1513382// GenerateAuthToken is a mighty big test.
13383// It tests all permutation of GenerateAuthToken behavior:
13384// - Synchronous and Asynchronous completion.
13385// - OK or error on completion.
13386// - Direct connection, non-authenticating proxy, and authenticating proxy.
13387// - HTTP or HTTPS backend (to include proxy tunneling).
13388// - Non-authenticating and authenticating backend.
13389//
[email protected]fe3b7dc2012-02-03 19:52:0913390// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1513391// problems generating an auth token for an authenticating proxy, we don't
13392// need to test all permutations of the backend server).
13393//
13394// The test proceeds by going over each of the configuration cases, and
13395// potentially running up to three rounds in each of the tests. The TestConfig
13396// specifies both the configuration for the test as well as the expectations
13397// for the results.
bncd16676a2016-07-20 16:23:0113398TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5013399 static const char kServer[] = "http://www.example.com";
13400 static const char kSecureServer[] = "https://www.example.com";
13401 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1513402
13403 enum AuthTiming {
13404 AUTH_NONE,
13405 AUTH_SYNC,
13406 AUTH_ASYNC,
13407 };
13408
13409 const MockWrite kGet(
13410 "GET / HTTP/1.1\r\n"
13411 "Host: www.example.com\r\n"
13412 "Connection: keep-alive\r\n\r\n");
13413 const MockWrite kGetProxy(
13414 "GET http://www.example.com/ HTTP/1.1\r\n"
13415 "Host: www.example.com\r\n"
13416 "Proxy-Connection: keep-alive\r\n\r\n");
13417 const MockWrite kGetAuth(
13418 "GET / HTTP/1.1\r\n"
13419 "Host: www.example.com\r\n"
13420 "Connection: keep-alive\r\n"
13421 "Authorization: auth_token\r\n\r\n");
13422 const MockWrite kGetProxyAuth(
13423 "GET http://www.example.com/ HTTP/1.1\r\n"
13424 "Host: www.example.com\r\n"
13425 "Proxy-Connection: keep-alive\r\n"
13426 "Proxy-Authorization: auth_token\r\n\r\n");
13427 const MockWrite kGetAuthThroughProxy(
13428 "GET http://www.example.com/ HTTP/1.1\r\n"
13429 "Host: www.example.com\r\n"
13430 "Proxy-Connection: keep-alive\r\n"
13431 "Authorization: auth_token\r\n\r\n");
13432 const MockWrite kGetAuthWithProxyAuth(
13433 "GET http://www.example.com/ HTTP/1.1\r\n"
13434 "Host: www.example.com\r\n"
13435 "Proxy-Connection: keep-alive\r\n"
13436 "Proxy-Authorization: auth_token\r\n"
13437 "Authorization: auth_token\r\n\r\n");
13438 const MockWrite kConnect(
13439 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713440 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513441 "Proxy-Connection: keep-alive\r\n\r\n");
13442 const MockWrite kConnectProxyAuth(
13443 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713444 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513445 "Proxy-Connection: keep-alive\r\n"
13446 "Proxy-Authorization: auth_token\r\n\r\n");
13447
13448 const MockRead kSuccess(
13449 "HTTP/1.1 200 OK\r\n"
13450 "Content-Type: text/html; charset=iso-8859-1\r\n"
13451 "Content-Length: 3\r\n\r\n"
13452 "Yes");
13453 const MockRead kFailure(
13454 "Should not be called.");
13455 const MockRead kServerChallenge(
13456 "HTTP/1.1 401 Unauthorized\r\n"
13457 "WWW-Authenticate: Mock realm=server\r\n"
13458 "Content-Type: text/html; charset=iso-8859-1\r\n"
13459 "Content-Length: 14\r\n\r\n"
13460 "Unauthorized\r\n");
13461 const MockRead kProxyChallenge(
13462 "HTTP/1.1 407 Unauthorized\r\n"
13463 "Proxy-Authenticate: Mock realm=proxy\r\n"
13464 "Proxy-Connection: close\r\n"
13465 "Content-Type: text/html; charset=iso-8859-1\r\n"
13466 "Content-Length: 14\r\n\r\n"
13467 "Unauthorized\r\n");
13468 const MockRead kProxyConnected(
13469 "HTTP/1.1 200 Connection Established\r\n\r\n");
13470
13471 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
13472 // no constructors, but the C++ compiler on Windows warns about
13473 // unspecified data in compound literals. So, moved to using constructors,
13474 // and TestRound's created with the default constructor should not be used.
13475 struct TestRound {
13476 TestRound()
Raul Tambre94493c652019-03-11 17:18:3513477 : expected_rv(ERR_UNEXPECTED),
13478 extra_write(nullptr),
13479 extra_read(nullptr) {}
Raul Tambre8335a6d2019-02-21 16:57:4313480 TestRound(const MockWrite& write_arg,
13481 const MockRead& read_arg,
[email protected]044de0642010-06-17 10:42:1513482 int expected_rv_arg)
13483 : write(write_arg),
13484 read(read_arg),
13485 expected_rv(expected_rv_arg),
Raul Tambre94493c652019-03-11 17:18:3513486 extra_write(nullptr),
13487 extra_read(nullptr) {}
[email protected]044de0642010-06-17 10:42:1513488 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
13489 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0113490 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1513491 : write(write_arg),
13492 read(read_arg),
13493 expected_rv(expected_rv_arg),
13494 extra_write(extra_write_arg),
13495 extra_read(extra_read_arg) {
13496 }
13497 MockWrite write;
13498 MockRead read;
13499 int expected_rv;
13500 const MockWrite* extra_write;
13501 const MockRead* extra_read;
13502 };
13503
13504 static const int kNoSSL = 500;
13505
13506 struct TestConfig {
asanka463ca4262016-11-16 02:34:3113507 int line_number;
thestig9d3bb0c2015-01-24 00:49:5113508 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1513509 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3113510 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5113511 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1513512 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3113513 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1513514 int num_auth_rounds;
13515 int first_ssl_round;
asankae2257db2016-10-11 22:03:1613516 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1513517 } test_configs[] = {
asankac93076192016-10-03 15:46:0213518 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113519 {__LINE__,
13520 nullptr,
asankac93076192016-10-03 15:46:0213521 AUTH_NONE,
13522 OK,
13523 kServer,
13524 AUTH_NONE,
13525 OK,
13526 1,
13527 kNoSSL,
13528 {TestRound(kGet, kSuccess, OK)}},
13529 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113530 {__LINE__,
13531 nullptr,
asankac93076192016-10-03 15:46:0213532 AUTH_NONE,
13533 OK,
13534 kServer,
13535 AUTH_SYNC,
13536 OK,
13537 2,
13538 kNoSSL,
13539 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513540 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113541 {__LINE__,
13542 nullptr,
asankac93076192016-10-03 15:46:0213543 AUTH_NONE,
13544 OK,
13545 kServer,
13546 AUTH_SYNC,
13547 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613548 3,
13549 kNoSSL,
13550 {TestRound(kGet, kServerChallenge, OK),
13551 TestRound(kGet, kServerChallenge, OK),
13552 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113553 {__LINE__,
13554 nullptr,
asankae2257db2016-10-11 22:03:1613555 AUTH_NONE,
13556 OK,
13557 kServer,
13558 AUTH_SYNC,
13559 ERR_UNSUPPORTED_AUTH_SCHEME,
13560 2,
13561 kNoSSL,
13562 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113563 {__LINE__,
13564 nullptr,
asankae2257db2016-10-11 22:03:1613565 AUTH_NONE,
13566 OK,
13567 kServer,
13568 AUTH_SYNC,
13569 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
13570 2,
13571 kNoSSL,
13572 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113573 {__LINE__,
13574 kProxy,
asankae2257db2016-10-11 22:03:1613575 AUTH_SYNC,
13576 ERR_FAILED,
13577 kServer,
13578 AUTH_NONE,
13579 OK,
13580 2,
13581 kNoSSL,
13582 {TestRound(kGetProxy, kProxyChallenge, OK),
13583 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113584 {__LINE__,
13585 kProxy,
asankae2257db2016-10-11 22:03:1613586 AUTH_ASYNC,
13587 ERR_FAILED,
13588 kServer,
13589 AUTH_NONE,
13590 OK,
13591 2,
13592 kNoSSL,
13593 {TestRound(kGetProxy, kProxyChallenge, OK),
13594 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113595 {__LINE__,
13596 nullptr,
asankae2257db2016-10-11 22:03:1613597 AUTH_NONE,
13598 OK,
13599 kServer,
13600 AUTH_SYNC,
13601 ERR_FAILED,
asankac93076192016-10-03 15:46:0213602 2,
13603 kNoSSL,
13604 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613605 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113606 {__LINE__,
13607 nullptr,
asankae2257db2016-10-11 22:03:1613608 AUTH_NONE,
13609 OK,
13610 kServer,
13611 AUTH_ASYNC,
13612 ERR_FAILED,
13613 2,
13614 kNoSSL,
13615 {TestRound(kGet, kServerChallenge, OK),
13616 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113617 {__LINE__,
13618 nullptr,
asankac93076192016-10-03 15:46:0213619 AUTH_NONE,
13620 OK,
13621 kServer,
13622 AUTH_ASYNC,
13623 OK,
13624 2,
13625 kNoSSL,
13626 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513627 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113628 {__LINE__,
13629 nullptr,
asankac93076192016-10-03 15:46:0213630 AUTH_NONE,
13631 OK,
13632 kServer,
13633 AUTH_ASYNC,
13634 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613635 3,
asankac93076192016-10-03 15:46:0213636 kNoSSL,
13637 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613638 // The second round uses a HttpAuthHandlerMock that always succeeds.
13639 TestRound(kGet, kServerChallenge, OK),
13640 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213641 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113642 {__LINE__,
13643 kProxy,
asankac93076192016-10-03 15:46:0213644 AUTH_NONE,
13645 OK,
13646 kServer,
13647 AUTH_NONE,
13648 OK,
13649 1,
13650 kNoSSL,
13651 {TestRound(kGetProxy, kSuccess, OK)}},
13652 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113653 {__LINE__,
13654 kProxy,
asankac93076192016-10-03 15:46:0213655 AUTH_NONE,
13656 OK,
13657 kServer,
13658 AUTH_SYNC,
13659 OK,
13660 2,
13661 kNoSSL,
13662 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513663 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113664 {__LINE__,
13665 kProxy,
asankac93076192016-10-03 15:46:0213666 AUTH_NONE,
13667 OK,
13668 kServer,
13669 AUTH_SYNC,
13670 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613671 3,
asankac93076192016-10-03 15:46:0213672 kNoSSL,
13673 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613674 TestRound(kGetProxy, kServerChallenge, OK),
13675 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113676 {__LINE__,
13677 kProxy,
asankac93076192016-10-03 15:46:0213678 AUTH_NONE,
13679 OK,
13680 kServer,
13681 AUTH_ASYNC,
13682 OK,
13683 2,
13684 kNoSSL,
13685 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513686 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113687 {__LINE__,
13688 kProxy,
asankac93076192016-10-03 15:46:0213689 AUTH_NONE,
13690 OK,
13691 kServer,
13692 AUTH_ASYNC,
13693 ERR_INVALID_AUTH_CREDENTIALS,
13694 2,
13695 kNoSSL,
13696 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613697 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213698 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113699 {__LINE__,
13700 kProxy,
asankac93076192016-10-03 15:46:0213701 AUTH_SYNC,
13702 OK,
13703 kServer,
13704 AUTH_NONE,
13705 OK,
13706 2,
13707 kNoSSL,
13708 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513709 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113710 {__LINE__,
13711 kProxy,
asankac93076192016-10-03 15:46:0213712 AUTH_SYNC,
13713 ERR_INVALID_AUTH_CREDENTIALS,
13714 kServer,
13715 AUTH_NONE,
13716 OK,
13717 2,
13718 kNoSSL,
13719 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613720 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113721 {__LINE__,
13722 kProxy,
asankac93076192016-10-03 15:46:0213723 AUTH_ASYNC,
13724 OK,
13725 kServer,
13726 AUTH_NONE,
13727 OK,
13728 2,
13729 kNoSSL,
13730 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513731 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113732 {__LINE__,
13733 kProxy,
asankac93076192016-10-03 15:46:0213734 AUTH_ASYNC,
13735 ERR_INVALID_AUTH_CREDENTIALS,
13736 kServer,
13737 AUTH_NONE,
13738 OK,
13739 2,
13740 kNoSSL,
13741 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613742 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113743 {__LINE__,
13744 kProxy,
13745 AUTH_ASYNC,
13746 ERR_INVALID_AUTH_CREDENTIALS,
13747 kServer,
13748 AUTH_NONE,
13749 OK,
13750 3,
13751 kNoSSL,
13752 {TestRound(kGetProxy, kProxyChallenge, OK),
13753 TestRound(kGetProxy, kProxyChallenge, OK),
13754 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213755 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113756 {__LINE__,
13757 kProxy,
asankac93076192016-10-03 15:46:0213758 AUTH_SYNC,
13759 OK,
13760 kServer,
13761 AUTH_SYNC,
13762 OK,
13763 3,
13764 kNoSSL,
13765 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513766 TestRound(kGetProxyAuth, kServerChallenge, OK),
13767 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113768 {__LINE__,
13769 kProxy,
asankac93076192016-10-03 15:46:0213770 AUTH_SYNC,
13771 OK,
13772 kServer,
13773 AUTH_SYNC,
13774 ERR_INVALID_AUTH_CREDENTIALS,
13775 3,
13776 kNoSSL,
13777 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513778 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613779 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113780 {__LINE__,
13781 kProxy,
asankac93076192016-10-03 15:46:0213782 AUTH_ASYNC,
13783 OK,
13784 kServer,
13785 AUTH_SYNC,
13786 OK,
13787 3,
13788 kNoSSL,
13789 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513790 TestRound(kGetProxyAuth, kServerChallenge, OK),
13791 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113792 {__LINE__,
13793 kProxy,
asankac93076192016-10-03 15:46:0213794 AUTH_ASYNC,
13795 OK,
13796 kServer,
13797 AUTH_SYNC,
13798 ERR_INVALID_AUTH_CREDENTIALS,
13799 3,
13800 kNoSSL,
13801 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513802 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613803 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113804 {__LINE__,
13805 kProxy,
asankac93076192016-10-03 15:46:0213806 AUTH_SYNC,
13807 OK,
13808 kServer,
13809 AUTH_ASYNC,
13810 OK,
13811 3,
13812 kNoSSL,
13813 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513814 TestRound(kGetProxyAuth, kServerChallenge, OK),
13815 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113816 {__LINE__,
13817 kProxy,
13818 AUTH_SYNC,
13819 ERR_INVALID_AUTH_CREDENTIALS,
13820 kServer,
13821 AUTH_ASYNC,
13822 OK,
13823 4,
13824 kNoSSL,
13825 {TestRound(kGetProxy, kProxyChallenge, OK),
13826 TestRound(kGetProxy, kProxyChallenge, OK),
13827 TestRound(kGetProxyAuth, kServerChallenge, OK),
13828 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
13829 {__LINE__,
13830 kProxy,
asankac93076192016-10-03 15:46:0213831 AUTH_SYNC,
13832 OK,
13833 kServer,
13834 AUTH_ASYNC,
13835 ERR_INVALID_AUTH_CREDENTIALS,
13836 3,
13837 kNoSSL,
13838 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513839 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613840 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113841 {__LINE__,
13842 kProxy,
asankac93076192016-10-03 15:46:0213843 AUTH_ASYNC,
13844 OK,
13845 kServer,
13846 AUTH_ASYNC,
13847 OK,
13848 3,
13849 kNoSSL,
13850 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513851 TestRound(kGetProxyAuth, kServerChallenge, OK),
13852 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113853 {__LINE__,
13854 kProxy,
asankac93076192016-10-03 15:46:0213855 AUTH_ASYNC,
13856 OK,
13857 kServer,
13858 AUTH_ASYNC,
13859 ERR_INVALID_AUTH_CREDENTIALS,
13860 3,
13861 kNoSSL,
13862 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513863 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613864 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113865 {__LINE__,
13866 kProxy,
13867 AUTH_ASYNC,
13868 ERR_INVALID_AUTH_CREDENTIALS,
13869 kServer,
13870 AUTH_ASYNC,
13871 ERR_INVALID_AUTH_CREDENTIALS,
13872 4,
13873 kNoSSL,
13874 {TestRound(kGetProxy, kProxyChallenge, OK),
13875 TestRound(kGetProxy, kProxyChallenge, OK),
13876 TestRound(kGetProxyAuth, kServerChallenge, OK),
13877 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213878 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113879 {__LINE__,
13880 nullptr,
asankac93076192016-10-03 15:46:0213881 AUTH_NONE,
13882 OK,
13883 kSecureServer,
13884 AUTH_NONE,
13885 OK,
13886 1,
13887 0,
13888 {TestRound(kGet, kSuccess, OK)}},
13889 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113890 {__LINE__,
13891 nullptr,
asankac93076192016-10-03 15:46:0213892 AUTH_NONE,
13893 OK,
13894 kSecureServer,
13895 AUTH_SYNC,
13896 OK,
13897 2,
13898 0,
13899 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513900 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113901 {__LINE__,
13902 nullptr,
asankac93076192016-10-03 15:46:0213903 AUTH_NONE,
13904 OK,
13905 kSecureServer,
13906 AUTH_SYNC,
13907 ERR_INVALID_AUTH_CREDENTIALS,
13908 2,
13909 0,
asankae2257db2016-10-11 22:03:1613910 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113911 {__LINE__,
13912 nullptr,
asankac93076192016-10-03 15:46:0213913 AUTH_NONE,
13914 OK,
13915 kSecureServer,
13916 AUTH_ASYNC,
13917 OK,
13918 2,
13919 0,
13920 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513921 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113922 {__LINE__,
13923 nullptr,
asankac93076192016-10-03 15:46:0213924 AUTH_NONE,
13925 OK,
13926 kSecureServer,
13927 AUTH_ASYNC,
13928 ERR_INVALID_AUTH_CREDENTIALS,
13929 2,
13930 0,
asankae2257db2016-10-11 22:03:1613931 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213932 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113933 {__LINE__,
13934 kProxy,
asankac93076192016-10-03 15:46:0213935 AUTH_NONE,
13936 OK,
13937 kSecureServer,
13938 AUTH_NONE,
13939 OK,
13940 1,
13941 0,
13942 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13943 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113944 {__LINE__,
13945 kProxy,
asankac93076192016-10-03 15:46:0213946 AUTH_NONE,
13947 OK,
13948 kSecureServer,
13949 AUTH_SYNC,
13950 OK,
13951 2,
13952 0,
13953 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513954 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113955 {__LINE__,
13956 kProxy,
asankac93076192016-10-03 15:46:0213957 AUTH_NONE,
13958 OK,
13959 kSecureServer,
13960 AUTH_SYNC,
13961 ERR_INVALID_AUTH_CREDENTIALS,
13962 2,
13963 0,
13964 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613965 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113966 {__LINE__,
13967 kProxy,
asankac93076192016-10-03 15:46:0213968 AUTH_NONE,
13969 OK,
13970 kSecureServer,
13971 AUTH_ASYNC,
13972 OK,
13973 2,
13974 0,
13975 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513976 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113977 {__LINE__,
13978 kProxy,
asankac93076192016-10-03 15:46:0213979 AUTH_NONE,
13980 OK,
13981 kSecureServer,
13982 AUTH_ASYNC,
13983 ERR_INVALID_AUTH_CREDENTIALS,
13984 2,
13985 0,
13986 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613987 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213988 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113989 {__LINE__,
13990 kProxy,
asankac93076192016-10-03 15:46:0213991 AUTH_SYNC,
13992 OK,
13993 kSecureServer,
13994 AUTH_NONE,
13995 OK,
13996 2,
13997 1,
13998 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513999 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114000 {__LINE__,
14001 kProxy,
asankac93076192016-10-03 15:46:0214002 AUTH_SYNC,
14003 ERR_INVALID_AUTH_CREDENTIALS,
14004 kSecureServer,
14005 AUTH_NONE,
14006 OK,
14007 2,
14008 kNoSSL,
14009 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1614010 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114011 {__LINE__,
14012 kProxy,
asankae2257db2016-10-11 22:03:1614013 AUTH_SYNC,
14014 ERR_UNSUPPORTED_AUTH_SCHEME,
14015 kSecureServer,
14016 AUTH_NONE,
14017 OK,
14018 2,
14019 kNoSSL,
14020 {TestRound(kConnect, kProxyChallenge, OK),
14021 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114022 {__LINE__,
14023 kProxy,
asankae2257db2016-10-11 22:03:1614024 AUTH_SYNC,
14025 ERR_UNEXPECTED,
14026 kSecureServer,
14027 AUTH_NONE,
14028 OK,
14029 2,
14030 kNoSSL,
14031 {TestRound(kConnect, kProxyChallenge, OK),
14032 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3114033 {__LINE__,
14034 kProxy,
asankac93076192016-10-03 15:46:0214035 AUTH_ASYNC,
14036 OK,
14037 kSecureServer,
14038 AUTH_NONE,
14039 OK,
14040 2,
14041 1,
14042 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1514043 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114044 {__LINE__,
14045 kProxy,
asankac93076192016-10-03 15:46:0214046 AUTH_ASYNC,
14047 ERR_INVALID_AUTH_CREDENTIALS,
14048 kSecureServer,
14049 AUTH_NONE,
14050 OK,
14051 2,
14052 kNoSSL,
14053 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1614054 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0214055 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3114056 {__LINE__,
14057 kProxy,
asankac93076192016-10-03 15:46:0214058 AUTH_SYNC,
14059 OK,
14060 kSecureServer,
14061 AUTH_SYNC,
14062 OK,
14063 3,
14064 1,
14065 {TestRound(kConnect, kProxyChallenge, OK),
14066 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14067 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514068 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114069 {__LINE__,
14070 kProxy,
asankac93076192016-10-03 15:46:0214071 AUTH_SYNC,
14072 OK,
14073 kSecureServer,
14074 AUTH_SYNC,
14075 ERR_INVALID_AUTH_CREDENTIALS,
14076 3,
14077 1,
14078 {TestRound(kConnect, kProxyChallenge, OK),
14079 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14080 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614081 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114082 {__LINE__,
14083 kProxy,
asankac93076192016-10-03 15:46:0214084 AUTH_ASYNC,
14085 OK,
14086 kSecureServer,
14087 AUTH_SYNC,
14088 OK,
14089 3,
14090 1,
14091 {TestRound(kConnect, kProxyChallenge, OK),
14092 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14093 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514094 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114095 {__LINE__,
14096 kProxy,
asankac93076192016-10-03 15:46:0214097 AUTH_ASYNC,
14098 OK,
14099 kSecureServer,
14100 AUTH_SYNC,
14101 ERR_INVALID_AUTH_CREDENTIALS,
14102 3,
14103 1,
14104 {TestRound(kConnect, kProxyChallenge, OK),
14105 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14106 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614107 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114108 {__LINE__,
14109 kProxy,
asankac93076192016-10-03 15:46:0214110 AUTH_SYNC,
14111 OK,
14112 kSecureServer,
14113 AUTH_ASYNC,
14114 OK,
14115 3,
14116 1,
14117 {TestRound(kConnect, kProxyChallenge, OK),
14118 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14119 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514120 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114121 {__LINE__,
14122 kProxy,
asankac93076192016-10-03 15:46:0214123 AUTH_SYNC,
14124 OK,
14125 kSecureServer,
14126 AUTH_ASYNC,
14127 ERR_INVALID_AUTH_CREDENTIALS,
14128 3,
14129 1,
14130 {TestRound(kConnect, kProxyChallenge, OK),
14131 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14132 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614133 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114134 {__LINE__,
14135 kProxy,
asankac93076192016-10-03 15:46:0214136 AUTH_ASYNC,
14137 OK,
14138 kSecureServer,
14139 AUTH_ASYNC,
14140 OK,
14141 3,
14142 1,
14143 {TestRound(kConnect, kProxyChallenge, OK),
14144 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14145 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514146 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114147 {__LINE__,
14148 kProxy,
asankac93076192016-10-03 15:46:0214149 AUTH_ASYNC,
14150 OK,
14151 kSecureServer,
14152 AUTH_ASYNC,
14153 ERR_INVALID_AUTH_CREDENTIALS,
14154 3,
14155 1,
14156 {TestRound(kConnect, kProxyChallenge, OK),
14157 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14158 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614159 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114160 {__LINE__,
14161 kProxy,
14162 AUTH_ASYNC,
14163 ERR_INVALID_AUTH_CREDENTIALS,
14164 kSecureServer,
14165 AUTH_ASYNC,
14166 ERR_INVALID_AUTH_CREDENTIALS,
14167 4,
14168 2,
14169 {TestRound(kConnect, kProxyChallenge, OK),
14170 TestRound(kConnect, kProxyChallenge, OK),
14171 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14172 &kServerChallenge),
14173 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1514174 };
14175
asanka463ca4262016-11-16 02:34:3114176 for (const auto& test_config : test_configs) {
14177 SCOPED_TRACE(::testing::Message() << "Test config at "
14178 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0814179 HttpAuthHandlerMock::Factory* auth_factory(
14180 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714181 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4914182 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2614183
14184 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1514185 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3114186 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0814187 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14188 std::string auth_challenge = "Mock realm=proxy";
14189 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2414190 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14191 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0814192 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2014193 empty_ssl_info, origin,
14194 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814195 auth_handler->SetGenerateExpectation(
14196 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114197 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0814198 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
14199 }
[email protected]044de0642010-06-17 10:42:1514200 }
14201 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0014202 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1514203 std::string auth_challenge = "Mock realm=server";
14204 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2414205 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14206 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1514207 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014208 empty_ssl_info, origin,
14209 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514210 auth_handler->SetGenerateExpectation(
14211 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114212 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0814213 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1614214
14215 // The second handler always succeeds. It should only be used where there
14216 // are multiple auth sessions for server auth in the same network
14217 // transaction using the same auth scheme.
14218 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1914219 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1614220 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
14221 empty_ssl_info, origin,
14222 NetLogWithSource());
14223 second_handler->SetGenerateExpectation(true, OK);
14224 auth_factory->AddMockHandler(second_handler.release(),
14225 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1514226 }
14227 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5914228 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914229 ProxyResolutionService::CreateFixed(test_config.proxy_url,
14230 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514231 } else {
Bence Béky53a5aef2018-03-29 21:54:1214232 session_deps_.proxy_resolution_service =
14233 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1514234 }
14235
14236 HttpRequestInfo request;
14237 request.method = "GET";
14238 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e2018-02-07 07:41:1014239 request.traffic_annotation =
14240 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514241
danakj1fd259a02016-04-16 03:17:0914242 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1514243
rchcb68dc62015-05-21 04:45:3614244 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
14245
14246 std::vector<std::vector<MockRead>> mock_reads(1);
14247 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1514248 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214249 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1514250 const TestRound& read_write_round = test_config.rounds[round];
14251
14252 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3614253 mock_reads.back().push_back(read_write_round.read);
14254 mock_writes.back().push_back(read_write_round.write);
14255
14256 // kProxyChallenge uses Proxy-Connection: close which means that the
14257 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5414258 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3614259 mock_reads.push_back(std::vector<MockRead>());
14260 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1514261 }
14262
rchcb68dc62015-05-21 04:45:3614263 if (read_write_round.extra_read) {
14264 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1514265 }
rchcb68dc62015-05-21 04:45:3614266 if (read_write_round.extra_write) {
14267 mock_writes.back().push_back(*read_write_round.extra_write);
14268 }
[email protected]044de0642010-06-17 10:42:1514269
14270 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1514271 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0714272 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1514273 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3614274 }
[email protected]044de0642010-06-17 10:42:1514275
danakj1fd259a02016-04-16 03:17:0914276 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3614277 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1914278 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:0114279 mock_reads[i], mock_writes[i]));
rchcb68dc62015-05-21 04:45:3614280 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3214281 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3614282 }
14283
mmenkecc2298e2015-12-07 18:20:1814284 // Transaction must be created after DataProviders, so it's destroyed before
14285 // they are as well.
14286 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14287
rchcb68dc62015-05-21 04:45:3614288 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214289 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3614290 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1514291 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4114292 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1514293 int rv;
14294 if (round == 0) {
tfarina42834112016-09-22 13:38:2014295 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514296 } else {
[email protected]49639fa2011-12-20 23:22:4114297 rv = trans.RestartWithAuth(
14298 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1514299 }
14300 if (rv == ERR_IO_PENDING)
14301 rv = callback.WaitForResult();
14302
14303 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1614304 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5014305 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5514306 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1514307 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
14308 continue;
14309 }
14310 if (round + 1 < test_config.num_auth_rounds) {
Emily Starkf2c9bbd2019-04-09 17:08:5814311 EXPECT_TRUE(response->auth_challenge.has_value());
[email protected]044de0642010-06-17 10:42:1514312 } else {
Emily Starkf2c9bbd2019-04-09 17:08:5814313 EXPECT_FALSE(response->auth_challenge.has_value());
asankae2257db2016-10-11 22:03:1614314 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1514315 }
14316 }
[email protected]e5ae96a2010-04-14 20:12:4514317 }
14318}
14319
bncd16676a2016-07-20 16:23:0114320TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1414321 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1414322 HttpAuthHandlerMock::Factory* auth_factory(
14323 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714324 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1214325 session_deps_.proxy_resolution_service =
14326 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0714327 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
[email protected]c871bce92010-07-15 21:51:1414328
14329 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14330 auth_handler->set_connection_based(true);
14331 std::string auth_challenge = "Mock realm=server";
14332 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2414333 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14334 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4914335 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1414336 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014337 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814338 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1414339
[email protected]c871bce92010-07-15 21:51:1414340 int rv = OK;
Raul Tambre94493c652019-03-11 17:18:3514341 const HttpResponseInfo* response = nullptr;
[email protected]c871bce92010-07-15 21:51:1414342 HttpRequestInfo request;
14343 request.method = "GET";
14344 request.url = origin;
Ramin Halavatib5e433e2018-02-07 07:41:1014345 request.traffic_annotation =
14346 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714347
danakj1fd259a02016-04-16 03:17:0914348 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1014349
14350 // Use a TCP Socket Pool with only one connection per group. This is used
14351 // to validate that the TCP socket is not released to the pool between
14352 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4214353 HttpNetworkSessionPeer session_peer(session.get());
Matt Menked6fd2a52019-03-20 06:14:3614354 CommonConnectJobParams common_connect_job_params(
14355 session->CreateCommonConnectJobParams());
[email protected]ab739042011-04-07 15:22:2814356 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
Tarun Bansala7635092019-02-20 10:00:5914357 50, // Max sockets for pool
14358 1, // Max sockets per group
14359 base::TimeDelta::FromSeconds(10), // unused_idle_socket_timeout
Matt Menkeaafff542019-04-22 22:09:3614360 ProxyServer::Direct(), false, // is_for_websockets
Matt Menked6fd2a52019-03-20 06:14:3614361 &common_connect_job_params, session_deps_.ssl_config_service.get());
Jeremy Roman0579ed62017-08-29 15:56:1914362 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4014363 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
14364 base::WrapUnique(transport_pool));
dchengc7eeda422015-12-26 03:56:4814365 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1014366
bnc691fda62016-08-12 00:43:1614367 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114368 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1414369
14370 const MockWrite kGet(
14371 "GET / HTTP/1.1\r\n"
14372 "Host: www.example.com\r\n"
14373 "Connection: keep-alive\r\n\r\n");
14374 const MockWrite kGetAuth(
14375 "GET / HTTP/1.1\r\n"
14376 "Host: www.example.com\r\n"
14377 "Connection: keep-alive\r\n"
14378 "Authorization: auth_token\r\n\r\n");
14379
14380 const MockRead kServerChallenge(
14381 "HTTP/1.1 401 Unauthorized\r\n"
14382 "WWW-Authenticate: Mock realm=server\r\n"
14383 "Content-Type: text/html; charset=iso-8859-1\r\n"
14384 "Content-Length: 14\r\n\r\n"
14385 "Unauthorized\r\n");
14386 const MockRead kSuccess(
14387 "HTTP/1.1 200 OK\r\n"
14388 "Content-Type: text/html; charset=iso-8859-1\r\n"
14389 "Content-Length: 3\r\n\r\n"
14390 "Yes");
14391
14392 MockWrite writes[] = {
14393 // First round
14394 kGet,
14395 // Second round
14396 kGetAuth,
14397 // Third round
14398 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3014399 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1014400 kGetAuth,
14401 // Competing request
14402 kGet,
[email protected]c871bce92010-07-15 21:51:1414403 };
14404 MockRead reads[] = {
14405 // First round
14406 kServerChallenge,
14407 // Second round
14408 kServerChallenge,
14409 // Third round
[email protected]eca50e122010-09-11 14:03:3014410 kServerChallenge,
14411 // Fourth round
[email protected]c871bce92010-07-15 21:51:1414412 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1014413 // Competing response
14414 kSuccess,
[email protected]c871bce92010-07-15 21:51:1414415 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114416 StaticSocketDataProvider data_provider(reads, writes);
[email protected]bb88e1d32013-05-03 23:11:0714417 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1414418
Matt Menkef6edce752019-03-19 17:21:5614419 const ClientSocketPool::GroupId kSocketGroup(
14420 HostPortPair("www.example.com", 80), ClientSocketPool::SocketType::kHttp,
Matt Menkebdf777802019-04-22 19:38:5914421 PrivacyMode::PRIVACY_MODE_DISABLED);
[email protected]7ef4cbbb2011-02-06 11:19:1014422
14423 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1414424 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2014425 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1414426 if (rv == ERR_IO_PENDING)
14427 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114428 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614429 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214430 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5814431 EXPECT_TRUE(response->auth_challenge.has_value());
Raul Tambre8335a6d2019-02-21 16:57:4314432 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114433 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14434 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414435
[email protected]7ef4cbbb2011-02-06 11:19:1014436 // In between rounds, another request comes in for the same domain.
14437 // It should not be able to grab the TCP socket that trans has already
14438 // claimed.
bnc691fda62016-08-12 00:43:1614439 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114440 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2014441 rv = trans_compete.Start(&request, callback_compete.callback(),
14442 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114443 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1014444 // callback_compete.WaitForResult at this point would stall forever,
14445 // since the HttpNetworkTransaction does not release the request back to
14446 // the pool until after authentication completes.
14447
14448 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1414449 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614450 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414451 if (rv == ERR_IO_PENDING)
14452 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114453 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614454 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214455 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5814456 EXPECT_FALSE(response->auth_challenge.has_value());
Raul Tambre8335a6d2019-02-21 16:57:4314457 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114458 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14459 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414460
[email protected]7ef4cbbb2011-02-06 11:19:1014461 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1414462 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614463 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414464 if (rv == ERR_IO_PENDING)
14465 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114466 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614467 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214468 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5814469 EXPECT_FALSE(response->auth_challenge.has_value());
Raul Tambre8335a6d2019-02-21 16:57:4314470 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114471 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14472 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3014473
[email protected]7ef4cbbb2011-02-06 11:19:1014474 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3014475 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614476 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3014477 if (rv == ERR_IO_PENDING)
14478 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114479 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614480 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214481 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5814482 EXPECT_FALSE(response->auth_challenge.has_value());
Raul Tambre8335a6d2019-02-21 16:57:4314483 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014484
asanka463ca4262016-11-16 02:34:3114485 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
14486 // auth handler should transition to a DONE state in concert with the remote
14487 // server. But that's not something we can test here with a mock handler.
14488 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
14489 auth_handler->state());
14490
[email protected]7ef4cbbb2011-02-06 11:19:1014491 // Read the body since the fourth round was successful. This will also
14492 // release the socket back to the pool.
Victor Costan9c7302b2018-08-27 16:39:4414493 scoped_refptr<IOBufferWithSize> io_buf =
14494 base::MakeRefCounted<IOBufferWithSize>(50);
bnc691fda62016-08-12 00:43:1614495 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014496 if (rv == ERR_IO_PENDING)
14497 rv = callback.WaitForResult();
14498 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614499 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014500 EXPECT_EQ(0, rv);
14501 // There are still 0 idle sockets, since the trans_compete transaction
14502 // will be handed it immediately after trans releases it to the group.
Raul Tambre8335a6d2019-02-21 16:57:4314503 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014504
14505 // The competing request can now finish. Wait for the headers and then
14506 // read the body.
14507 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0114508 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614509 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014510 if (rv == ERR_IO_PENDING)
14511 rv = callback.WaitForResult();
14512 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614513 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014514 EXPECT_EQ(0, rv);
14515
14516 // Finally, the socket is released to the group.
Raul Tambre8335a6d2019-02-21 16:57:4314517 EXPECT_EQ(1u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1414518}
14519
[email protected]65041fa2010-05-21 06:56:5314520// This tests the case that a request is issued via http instead of spdy after
14521// npn is negotiated.
bncd16676a2016-07-20 16:23:0114522TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5314523 HttpRequestInfo request;
14524 request.method = "GET";
bncce36dca22015-04-21 22:11:2314525 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014526 request.traffic_annotation =
14527 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5314528
14529 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314530 MockWrite(
14531 "GET / HTTP/1.1\r\n"
14532 "Host: www.example.org\r\n"
14533 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5314534 };
14535
14536 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5214537 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4314538 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5214539 MockRead("\r\n"),
14540 MockRead("hello world"),
14541 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5314542 };
14543
[email protected]8ddf8322012-02-23 18:08:0614544 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614545 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5314546
[email protected]bb88e1d32013-05-03 23:11:0714547 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5314548
Ryan Sleevib8d7ea02018-05-07 20:01:0114549 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714550 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5314551
[email protected]49639fa2011-12-20 23:22:4114552 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5314553
danakj1fd259a02016-04-16 03:17:0914554 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614555 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5314556
tfarina42834112016-09-22 13:38:2014557 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5314558
robpercival214763f2016-07-01 23:27:0114559 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14560 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5314561
bnc691fda62016-08-12 00:43:1614562 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214563 ASSERT_TRUE(response);
14564 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5314565 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14566
14567 std::string response_data;
bnc691fda62016-08-12 00:43:1614568 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5314569 EXPECT_EQ("hello world", response_data);
14570
14571 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214572 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5314573}
[email protected]26ef6582010-06-24 02:30:4714574
bnc55ff9da2015-08-19 18:42:3514575// Simulate the SSL handshake completing with an NPN negotiation followed by an
14576// immediate server closing of the socket.
14577// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0114578TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4714579 HttpRequestInfo request;
14580 request.method = "GET";
bncce36dca22015-04-21 22:11:2314581 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014582 request.traffic_annotation =
14583 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4714584
[email protected]8ddf8322012-02-23 18:08:0614585 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614586 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714587 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4714588
Ryan Hamilton0239aac2018-05-19 00:03:1314589 spdy::SpdySerializedFrame req(
14590 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114591 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4714592
14593 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614594 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4714595 };
14596
Ryan Sleevib8d7ea02018-05-07 20:01:0114597 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714598 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4714599
[email protected]49639fa2011-12-20 23:22:4114600 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4714601
danakj1fd259a02016-04-16 03:17:0914602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4714604
tfarina42834112016-09-22 13:38:2014605 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114606 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14607 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4714608}
[email protected]65d34382010-07-01 18:12:2614609
[email protected]795cbf82013-07-22 09:37:2714610// A subclass of HttpAuthHandlerMock that records the request URL when
14611// it gets it. This is needed since the auth handler may get destroyed
14612// before we get a chance to query it.
14613class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
14614 public:
14615 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
14616
Chris Watkins7a41d3552017-12-01 02:13:2714617 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2714618
14619 protected:
dchengb03027d2014-10-21 12:00:2014620 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
14621 const HttpRequestInfo* request,
Bence Béky7236fb72018-08-01 14:35:0914622 CompletionOnceCallback callback,
dchengb03027d2014-10-21 12:00:2014623 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2714624 *url_ = request->url;
14625 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
Bence Béky7236fb72018-08-01 14:35:0914626 credentials, request, std::move(callback), auth_token);
[email protected]795cbf82013-07-22 09:37:2714627 }
14628
14629 private:
14630 GURL* url_;
14631};
14632
[email protected]8e6441ca2010-08-19 05:56:3814633// Test that if we cancel the transaction as the connection is completing, that
14634// everything tears down correctly.
bncd16676a2016-07-20 16:23:0114635TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3814636 // Setup everything about the connection to complete synchronously, so that
14637 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
14638 // for is the callback from the HttpStreamRequest.
14639 // Then cancel the transaction.
14640 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3614641 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3814642 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614643 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
14644 MockRead(SYNCHRONOUS, "hello world"),
14645 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3814646 };
14647
[email protected]8e6441ca2010-08-19 05:56:3814648 HttpRequestInfo request;
14649 request.method = "GET";
bncce36dca22015-04-21 22:11:2314650 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014651 request.traffic_annotation =
14652 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3814653
danakj1fd259a02016-04-16 03:17:0914654 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5814655 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1914656 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2714657
Ryan Sleevib8d7ea02018-05-07 20:01:0114658 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]8e6441ca2010-08-19 05:56:3814659 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0714660 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3814661
[email protected]49639fa2011-12-20 23:22:4114662 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3814663
vishal.b62985ca92015-04-17 08:45:5114664 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4114665 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114666 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3814667 trans.reset(); // Cancel the transaction here.
14668
fdoray92e35a72016-06-10 15:54:5514669 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3014670}
14671
[email protected]ecab6e052014-05-16 14:58:1214672// Test that if a transaction is cancelled after receiving the headers, the
14673// stream is drained properly and added back to the socket pool. The main
14674// purpose of this test is to make sure that an HttpStreamParser can be read
14675// from after the HttpNetworkTransaction and the objects it owns have been
14676// deleted.
14677// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0114678TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1214679 MockRead data_reads[] = {
14680 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
14681 MockRead(ASYNC, "Content-Length: 2\r\n"),
14682 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
14683 MockRead(ASYNC, "1"),
14684 // 2 async reads are necessary to trigger a ReadResponseBody call after the
14685 // HttpNetworkTransaction has been deleted.
14686 MockRead(ASYNC, "2"),
14687 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
14688 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114689 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]ecab6e052014-05-16 14:58:1214690 session_deps_.socket_factory->AddSocketDataProvider(&data);
14691
danakj1fd259a02016-04-16 03:17:0914692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1214693
14694 {
14695 HttpRequestInfo request;
14696 request.method = "GET";
bncce36dca22015-04-21 22:11:2314697 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014698 request.traffic_annotation =
14699 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1214700
dcheng48459ac22014-08-26 00:46:4114701 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1214702 TestCompletionCallback callback;
14703
tfarina42834112016-09-22 13:38:2014704 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114705 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1214706 callback.WaitForResult();
14707
14708 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214709 ASSERT_TRUE(response);
14710 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1214711 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14712
14713 // The transaction and HttpRequestInfo are deleted.
14714 }
14715
14716 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5514717 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1214718
14719 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4114720 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1214721}
14722
[email protected]76a505b2010-08-25 06:23:0014723// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0114724TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914725 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914726 ProxyResolutionService::CreateFixedFromPacResult(
14727 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114728 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714729 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914730 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014731
[email protected]76a505b2010-08-25 06:23:0014732 HttpRequestInfo request;
14733 request.method = "GET";
bncce36dca22015-04-21 22:11:2314734 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014735 request.traffic_annotation =
14736 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014737
14738 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2314739 MockWrite(
14740 "GET http://www.example.org/ HTTP/1.1\r\n"
14741 "Host: www.example.org\r\n"
14742 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014743 };
14744
14745 MockRead data_reads1[] = {
14746 MockRead("HTTP/1.1 200 OK\r\n"),
14747 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14748 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614749 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014750 };
14751
Ryan Sleevib8d7ea02018-05-07 20:01:0114752 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714753 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0014754
[email protected]49639fa2011-12-20 23:22:4114755 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014756
bnc691fda62016-08-12 00:43:1614757 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914758 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614759 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914760 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14761 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014762
bnc691fda62016-08-12 00:43:1614763 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114764 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014765
14766 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114767 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0014768
bnc691fda62016-08-12 00:43:1614769 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214770 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014771
14772 EXPECT_TRUE(response->headers->IsKeepAlive());
14773 EXPECT_EQ(200, response->headers->response_code());
14774 EXPECT_EQ(100, response->headers->GetContentLength());
14775 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714776 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14777 HostPortPair::FromString("myproxy:70")),
14778 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914779 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14780 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14781 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0014782 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2014783
14784 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614785 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014786 TestLoadTimingNotReusedWithPac(load_timing_info,
14787 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0014788}
14789
14790// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0114791TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914792 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914793 ProxyResolutionService::CreateFixedFromPacResult(
14794 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114795 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714796 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914797 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014798
[email protected]76a505b2010-08-25 06:23:0014799 HttpRequestInfo request;
14800 request.method = "GET";
bncce36dca22015-04-21 22:11:2314801 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014802 request.traffic_annotation =
14803 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014804
14805 // Since we have proxy, should try to establish tunnel.
14806 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714807 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14808 "Host: www.example.org:443\r\n"
14809 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014810
rsleevidb16bb02015-11-12 23:47:1714811 MockWrite("GET / HTTP/1.1\r\n"
14812 "Host: www.example.org\r\n"
14813 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014814 };
14815
14816 MockRead data_reads1[] = {
14817 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14818
14819 MockRead("HTTP/1.1 200 OK\r\n"),
14820 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14821 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614822 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014823 };
14824
Ryan Sleevib8d7ea02018-05-07 20:01:0114825 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714826 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614827 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714828 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014829
[email protected]49639fa2011-12-20 23:22:4114830 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014831
bnc691fda62016-08-12 00:43:1614832 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914833 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614834 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914835 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14836 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014837
bnc691fda62016-08-12 00:43:1614838 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114839 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014840
14841 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114842 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4614843 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014844 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014845 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014846 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14847 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014848 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014849 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014850 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14851 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014852
bnc691fda62016-08-12 00:43:1614853 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214854 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014855
14856 EXPECT_TRUE(response->headers->IsKeepAlive());
14857 EXPECT_EQ(200, response->headers->response_code());
14858 EXPECT_EQ(100, response->headers->GetContentLength());
14859 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14860 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714861 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14862 HostPortPair::FromString("myproxy:70")),
14863 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914864 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14865 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14866 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2014867
14868 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614869 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014870 TestLoadTimingNotReusedWithPac(load_timing_info,
14871 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0014872}
14873
rsleevidb16bb02015-11-12 23:47:1714874// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
14875// literal host.
bncd16676a2016-07-20 16:23:0114876TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5914877 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914878 ProxyResolutionService::CreateFixedFromPacResult(
14879 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714880 BoundTestNetLog log;
14881 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914882 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1714883
14884 HttpRequestInfo request;
14885 request.method = "GET";
Eric Romanda790f92018-11-07 19:17:1514886 request.url = GURL("https://[::2]:443/");
Ramin Halavatib5e433e2018-02-07 07:41:1014887 request.traffic_annotation =
14888 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714889
14890 // Since we have proxy, should try to establish tunnel.
14891 MockWrite data_writes1[] = {
Eric Romanda790f92018-11-07 19:17:1514892 MockWrite("CONNECT [::2]:443 HTTP/1.1\r\n"
14893 "Host: [::2]:443\r\n"
rsleevidb16bb02015-11-12 23:47:1714894 "Proxy-Connection: keep-alive\r\n\r\n"),
14895
14896 MockWrite("GET / HTTP/1.1\r\n"
Eric Romanda790f92018-11-07 19:17:1514897 "Host: [::2]\r\n"
rsleevidb16bb02015-11-12 23:47:1714898 "Connection: keep-alive\r\n\r\n"),
14899 };
14900
14901 MockRead data_reads1[] = {
14902 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14903
14904 MockRead("HTTP/1.1 200 OK\r\n"),
14905 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14906 MockRead("Content-Length: 100\r\n\r\n"),
14907 MockRead(SYNCHRONOUS, OK),
14908 };
14909
Ryan Sleevib8d7ea02018-05-07 20:01:0114910 StaticSocketDataProvider data1(data_reads1, data_writes1);
rsleevidb16bb02015-11-12 23:47:1714911 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14912 SSLSocketDataProvider ssl(ASYNC, OK);
14913 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14914
14915 TestCompletionCallback callback1;
14916
bnc691fda62016-08-12 00:43:1614917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714918
bnc691fda62016-08-12 00:43:1614919 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714921
14922 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114923 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714924 TestNetLogEntry::List entries;
14925 log.GetEntries(&entries);
14926 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014927 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14928 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714929 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014930 entries, pos,
14931 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14932 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714933
bnc691fda62016-08-12 00:43:1614934 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214935 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714936
14937 EXPECT_TRUE(response->headers->IsKeepAlive());
14938 EXPECT_EQ(200, response->headers->response_code());
14939 EXPECT_EQ(100, response->headers->GetContentLength());
14940 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14941 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714942 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14943 HostPortPair::FromString("myproxy:70")),
14944 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714945
14946 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614947 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714948 TestLoadTimingNotReusedWithPac(load_timing_info,
14949 CONNECT_TIMING_HAS_SSL_TIMES);
14950}
14951
[email protected]76a505b2010-08-25 06:23:0014952// Test a basic HTTPS GET request through a proxy, but the server hangs up
14953// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114954TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4914955 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14956 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114957 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714958 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914959 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014960
[email protected]76a505b2010-08-25 06:23:0014961 HttpRequestInfo request;
14962 request.method = "GET";
bncce36dca22015-04-21 22:11:2314963 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014964 request.traffic_annotation =
14965 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014966
14967 // Since we have proxy, should try to establish tunnel.
14968 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714969 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14970 "Host: www.example.org:443\r\n"
14971 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014972
rsleevidb16bb02015-11-12 23:47:1714973 MockWrite("GET / HTTP/1.1\r\n"
14974 "Host: www.example.org\r\n"
14975 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014976 };
14977
14978 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014979 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614980 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014981 };
14982
Ryan Sleevib8d7ea02018-05-07 20:01:0114983 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714984 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614985 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714986 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014987
[email protected]49639fa2011-12-20 23:22:4114988 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014989
bnc691fda62016-08-12 00:43:1614990 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014991
bnc691fda62016-08-12 00:43:1614992 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114993 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014994
14995 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114996 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614997 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014998 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014999 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0015000 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
15001 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0015002 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4015003 entries, pos,
mikecirone8b85c432016-09-08 19:11:0015004 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
15005 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0015006}
15007
[email protected]749eefa82010-09-13 22:14:0315008// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0115009TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
Ryan Hamilton0239aac2018-05-19 00:03:1315010 spdy::SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4915011 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115012 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0315013
Raul Tambre94493c652019-03-11 17:18:3515014 spdy::SpdySerializedFrame resp(
15015 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315016 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0315017 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115018 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0315019 };
15020
Ryan Sleevib8d7ea02018-05-07 20:01:0115021 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715022 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0315023
[email protected]8ddf8322012-02-23 18:08:0615024 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615025 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715026 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0315027
danakj1fd259a02016-04-16 03:17:0915028 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0315029
15030 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2315031 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4015032 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1115033 PRIVACY_MODE_DISABLED,
15034 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2715035 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5215036 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0315037
15038 HttpRequestInfo request;
15039 request.method = "GET";
bncce36dca22015-04-21 22:11:2315040 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015041 request.traffic_annotation =
15042 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0315043
bnc691fda62016-08-12 00:43:1615044 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0315045
[email protected]41d64e82013-07-03 22:44:2615046 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015047 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115048 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15049 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0315050}
15051
[email protected]73b8dd222010-11-11 19:55:2415052// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1615053// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0215054void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0715055 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2915056 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715057 request_info.url = GURL("https://www.example.com/");
15058 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915059 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015060 request_info.traffic_annotation =
15061 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715062
[email protected]8ddf8322012-02-23 18:08:0615063 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2915064 MockWrite data_writes[] = {
15065 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2415066 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115067 StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
[email protected]bb88e1d32013-05-03 23:11:0715068 session_deps_.socket_factory->AddSocketDataProvider(&data);
15069 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2415070
danakj1fd259a02016-04-16 03:17:0915071 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615072 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2415073
[email protected]49639fa2011-12-20 23:22:4115074 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015075 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2915076 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2415077 rv = callback.WaitForResult();
15078 ASSERT_EQ(error, rv);
15079}
15080
bncd16676a2016-07-20 16:23:0115081TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2415082 // Just check a grab bag of cert errors.
15083 static const int kErrors[] = {
15084 ERR_CERT_COMMON_NAME_INVALID,
15085 ERR_CERT_AUTHORITY_INVALID,
15086 ERR_CERT_DATE_INVALID,
15087 };
Avi Drissman4365a4782018-12-28 19:26:2415088 for (size_t i = 0; i < base::size(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0615089 CheckErrorIsPassedBack(kErrors[i], ASYNC);
15090 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2415091 }
15092}
15093
[email protected]bd0b6772011-01-11 19:59:3015094// Ensure that a client certificate is removed from the SSL client auth
15095// cache when:
15096// 1) No proxy is involved.
15097// 2) TLS False Start is disabled.
15098// 3) The initial TLS handshake requests a client certificate.
15099// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115100TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915101 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715102 request_info.url = GURL("https://www.example.com/");
15103 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915104 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015105 request_info.traffic_annotation =
15106 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715107
[email protected]bd0b6772011-01-11 19:59:3015108 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115109 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015110
15111 // [ssl_]data1 contains the data for the first SSL handshake. When a
15112 // CertificateRequest is received for the first time, the handshake will
15113 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2915114 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015115 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715116 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115117 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715118 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015119
15120 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
15121 // False Start is not being used, the result of the SSL handshake will be
15122 // returned as part of the SSLClientSocket::Connect() call. This test
15123 // matches the result of a server sending a handshake_failure alert,
15124 // rather than a Finished message, because it requires a client
15125 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2915126 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3015127 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715128 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115129 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715130 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015131
15132 // [ssl_]data3 contains the data for the third SSL handshake. When a
15133 // connection to a server fails during an SSL handshake,
Steven Valdez0ef94d02018-11-19 23:28:1315134 // HttpNetworkTransaction will attempt to fallback to TLSv1.2 if the previous
15135 // connection was attempted with TLSv1.3. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3015136 // of the HttpNetworkTransaction. Because this test failure is due to
15137 // requiring a client certificate, this fallback handshake should also
15138 // fail.
ttuttle859dc7a2015-04-23 19:42:2915139 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
Steven Valdez0ef94d02018-11-19 23:28:1315140 ssl_data3.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
[email protected]bd0b6772011-01-11 19:59:3015141 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715142 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115143 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715144 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015145
[email protected]80c75f682012-05-26 16:22:1715146 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
15147 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4215148 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
15149 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1715150 // of the HttpNetworkTransaction. Because this test failure is due to
15151 // requiring a client certificate, this fallback handshake should also
15152 // fail.
ttuttle859dc7a2015-04-23 19:42:2915153 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1715154 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715155 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115156 StaticSocketDataProvider data4;
[email protected]bb88e1d32013-05-03 23:11:0715157 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715158
danakj1fd259a02016-04-16 03:17:0915159 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615160 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015161
[email protected]bd0b6772011-01-11 19:59:3015162 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4115163 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015164 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115165 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015166
15167 // Complete the SSL handshake, which should abort due to requiring a
15168 // client certificate.
15169 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115170 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015171
15172 // Indicate that no certificate should be supplied. From the perspective
15173 // of SSLClientCertCache, NULL is just as meaningful as a real
15174 // certificate, so this is the same as supply a
15175 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515176 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115177 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015178
15179 // Ensure the certificate was added to the client auth cache before
15180 // allowing the connection to continue restarting.
15181 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415182 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115183 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415184 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215185 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015186
15187 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715188 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15189 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015190 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115191 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015192
15193 // Ensure that the client certificate is removed from the cache on a
15194 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115195 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415196 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015197}
15198
15199// Ensure that a client certificate is removed from the SSL client auth
15200// cache when:
15201// 1) No proxy is involved.
15202// 2) TLS False Start is enabled.
15203// 3) The initial TLS handshake requests a client certificate.
15204// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115205TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915206 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715207 request_info.url = GURL("https://www.example.com/");
15208 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915209 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015210 request_info.traffic_annotation =
15211 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715212
[email protected]bd0b6772011-01-11 19:59:3015213 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115214 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015215
15216 // When TLS False Start is used, SSLClientSocket::Connect() calls will
15217 // return successfully after reading up to the peer's Certificate message.
15218 // This is to allow the caller to call SSLClientSocket::Write(), which can
15219 // enqueue application data to be sent in the same packet as the
15220 // ChangeCipherSpec and Finished messages.
15221 // The actual handshake will be finished when SSLClientSocket::Read() is
15222 // called, which expects to process the peer's ChangeCipherSpec and
15223 // Finished messages. If there was an error negotiating with the peer,
15224 // such as due to the peer requiring a client certificate when none was
15225 // supplied, the alert sent by the peer won't be processed until Read() is
15226 // called.
15227
15228 // Like the non-False Start case, when a client certificate is requested by
15229 // the peer, the handshake is aborted during the Connect() call.
15230 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2915231 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015232 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715233 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115234 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715235 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015236
15237 // When a client certificate is supplied, Connect() will not be aborted
15238 // when the peer requests the certificate. Instead, the handshake will
15239 // artificially succeed, allowing the caller to write the HTTP request to
15240 // the socket. The handshake messages are not processed until Read() is
15241 // called, which then detects that the handshake was aborted, due to the
15242 // peer sending a handshake_failure because it requires a client
15243 // certificate.
ttuttle859dc7a2015-04-23 19:42:2915244 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015245 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715246 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2915247 MockRead data2_reads[] = {
15248 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3015249 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115250 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715251 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015252
15253 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1715254 // the data for the SSL handshake once the TLSv1.1 connection falls back to
15255 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915256 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015257 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715258 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115259 StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715260 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015261
[email protected]80c75f682012-05-26 16:22:1715262 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
15263 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915264 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1715265 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715266 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115267 StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715268 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715269
[email protected]7799de12013-05-30 05:52:5115270 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2915271 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5115272 ssl_data5.cert_request_info = cert_request.get();
15273 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
Ryan Sleevib8d7ea02018-05-07 20:01:0115274 StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
[email protected]7799de12013-05-30 05:52:5115275 session_deps_.socket_factory->AddSocketDataProvider(&data5);
15276
danakj1fd259a02016-04-16 03:17:0915277 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615278 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015279
[email protected]bd0b6772011-01-11 19:59:3015280 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4115281 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015282 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115283 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015284
15285 // Complete the SSL handshake, which should abort due to requiring a
15286 // client certificate.
15287 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115288 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015289
15290 // Indicate that no certificate should be supplied. From the perspective
15291 // of SSLClientCertCache, NULL is just as meaningful as a real
15292 // certificate, so this is the same as supply a
15293 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515294 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115295 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015296
15297 // Ensure the certificate was added to the client auth cache before
15298 // allowing the connection to continue restarting.
15299 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415300 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115301 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415302 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215303 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015304
[email protected]bd0b6772011-01-11 19:59:3015305 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715306 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15307 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015308 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115309 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015310
15311 // Ensure that the client certificate is removed from the cache on a
15312 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115313 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415314 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015315}
15316
[email protected]8c405132011-01-11 22:03:1815317// Ensure that a client certificate is removed from the SSL client auth
15318// cache when:
15319// 1) An HTTPS proxy is involved.
15320// 3) The HTTPS proxy requests a client certificate.
15321// 4) The client supplies an invalid/unacceptable certificate for the
15322// proxy.
15323// The test is repeated twice, first for connecting to an HTTPS endpoint,
15324// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0115325TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4915326 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
15327 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115328 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715329 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1815330
15331 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115332 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1815333
15334 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
15335 // [ssl_]data[1-3]. Rather than represending the endpoint
15336 // (www.example.com:443), they represent failures with the HTTPS proxy
15337 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2915338 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1815339 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715340 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115341 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715342 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1815343
ttuttle859dc7a2015-04-23 19:42:2915344 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815345 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715346 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115347 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715348 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1815349
[email protected]80c75f682012-05-26 16:22:1715350 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
15351#if 0
ttuttle859dc7a2015-04-23 19:42:2915352 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815353 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715354 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115355 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715356 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1715357#endif
[email protected]8c405132011-01-11 22:03:1815358
ttuttle859dc7a2015-04-23 19:42:2915359 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1815360 requests[0].url = GURL("https://www.example.com/");
15361 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915362 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015363 requests[0].traffic_annotation =
15364 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815365
15366 requests[1].url = GURL("http://www.example.com/");
15367 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915368 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015369 requests[1].traffic_annotation =
15370 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815371
Avi Drissman4365a4782018-12-28 19:26:2415372 for (size_t i = 0; i < base::size(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0715373 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0915374 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615375 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1815376
15377 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4115378 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015379 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115380 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815381
15382 // Complete the SSL handshake, which should abort due to requiring a
15383 // client certificate.
15384 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115385 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1815386
15387 // Indicate that no certificate should be supplied. From the perspective
15388 // of SSLClientCertCache, NULL is just as meaningful as a real
15389 // certificate, so this is the same as supply a
15390 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515391 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115392 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815393
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;
svaldez7872fd02015-11-19 21:10:5415397 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115398 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415399 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215400 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1815401 // Ensure the certificate was NOT cached for the endpoint. This only
15402 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4115403 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415404 HostPortPair("www.example.com", 443), &client_cert,
15405 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815406
15407 // Restart the handshake. This will consume ssl_data2, which fails, and
15408 // then consume ssl_data3, which should also fail. The result code is
15409 // checked against what ssl_data3 should return.
15410 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115411 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1815412
15413 // Now that the new handshake has failed, ensure that the client
15414 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4115415 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415416 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4115417 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415418 HostPortPair("www.example.com", 443), &client_cert,
15419 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815420 }
15421}
15422
bncd16676a2016-07-20 16:23:0115423TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4615424 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915425 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915426 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615427
bnc032658ba2016-09-26 18:17:1515428 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615429
Ryan Hamilton0239aac2018-05-19 00:03:1315430 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915431 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815432 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315433 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715434 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615435 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115436 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615437 };
Ryan Hamilton0239aac2018-05-19 00:03:1315438 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515439 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315440 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115441 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315442 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515443 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315444 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115445 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615446 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115447 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15448 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315449 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615450 };
15451
eroman36d84e54432016-03-17 03:23:0215452 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215453 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115454 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715455 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615456
[email protected]aa22b242011-11-16 18:58:2915457 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615458 HttpRequestInfo request1;
15459 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315460 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615461 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015462 request1.traffic_annotation =
15463 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015464 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615465
tfarina42834112016-09-22 13:38:2015466 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15468 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615469
15470 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215471 ASSERT_TRUE(response);
15472 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215473 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615474
15475 std::string response_data;
robpercival214763f2016-07-01 23:27:0115476 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615477 EXPECT_EQ("hello!", response_data);
15478
bnca4d611d2016-09-22 19:55:3715479 // Preload mail.example.com into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315480 rv = session_deps_.host_resolver->LoadIntoCache(
15481 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115482 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615483
15484 HttpRequestInfo request2;
15485 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715486 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615487 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015488 request2.traffic_annotation =
15489 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015490 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615491
tfarina42834112016-09-22 13:38:2015492 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115493 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15494 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615495
15496 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215497 ASSERT_TRUE(response);
15498 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215499 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615500 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215501 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115502 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615503 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615504}
15505
bncd16676a2016-07-20 16:23:0115506TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0215507 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915508 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915509 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0215510
bnc032658ba2016-09-26 18:17:1515511 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0215512
Ryan Hamilton0239aac2018-05-19 00:03:1315513 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915514 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815515 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315516 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715517 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0215518 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115519 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0215520 };
Ryan Hamilton0239aac2018-05-19 00:03:1315521 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515522 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315523 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115524 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315525 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515526 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315527 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115528 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0215529 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115530 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15531 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315532 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0215533 };
15534
eroman36d84e54432016-03-17 03:23:0215535 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215536 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115537 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715538 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0215539
15540 TestCompletionCallback callback;
15541 HttpRequestInfo request1;
15542 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315543 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0215544 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015545 request1.traffic_annotation =
15546 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015547 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215548
tfarina42834112016-09-22 13:38:2015549 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115550 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15551 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215552
15553 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215554 ASSERT_TRUE(response);
15555 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215556 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215557
15558 std::string response_data;
robpercival214763f2016-07-01 23:27:0115559 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215560 EXPECT_EQ("hello!", response_data);
15561
15562 HttpRequestInfo request2;
15563 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715564 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0215565 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015566 request2.traffic_annotation =
15567 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015568 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215569
tfarina42834112016-09-22 13:38:2015570 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115571 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15572 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215573
15574 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215575 ASSERT_TRUE(response);
15576 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215577 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215578 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215579 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115580 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215581 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0215582}
15583
bnc8016c1f2017-03-31 02:11:2915584// Regression test for https://crbug.com/546991.
15585// The server might not be able to serve an IP pooled request, and might send a
15586// 421 Misdirected Request response status to indicate this.
15587// HttpNetworkTransaction should reset the request and retry without IP pooling.
15588TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
15589 // Two hosts resolve to the same IP address.
15590 const std::string ip_addr = "1.2.3.4";
15591 IPAddress ip;
15592 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15593 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15594
Jeremy Roman0579ed62017-08-29 15:56:1915595 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2915596 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15597 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15598
15599 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15600
15601 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315602 spdy::SpdySerializedFrame req1(
bnc8016c1f2017-03-31 02:11:2915603 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15604 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315605 spdy::SpdySerializedFrame req2(
bnc8016c1f2017-03-31 02:11:2915606 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315607 spdy::SpdySerializedFrame rst(
15608 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
bnc8016c1f2017-03-31 02:11:2915609 MockWrite writes1[] = {
15610 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15611 CreateMockWrite(rst, 6),
15612 };
15613
15614 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315615 spdy::SpdySerializedFrame resp1(
15616 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15617 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15618 spdy::SpdyHeaderBlock response_headers;
15619 response_headers[spdy::kHttp2StatusHeader] = "421";
15620 spdy::SpdySerializedFrame resp2(
bnc8016c1f2017-03-31 02:11:2915621 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
15622 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15623 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15624
15625 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115626 SequencedSocketData data1(connect1, reads1, writes1);
bnc8016c1f2017-03-31 02:11:2915627 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15628
15629 AddSSLSocketData();
15630
15631 // Retry the second request on a second connection.
15632 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315633 spdy::SpdySerializedFrame req3(
bnc8016c1f2017-03-31 02:11:2915634 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15635 MockWrite writes2[] = {
15636 CreateMockWrite(req3, 0),
15637 };
15638
Ryan Hamilton0239aac2018-05-19 00:03:1315639 spdy::SpdySerializedFrame resp3(
15640 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
15641 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
bnc8016c1f2017-03-31 02:11:2915642 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15643 MockRead(ASYNC, 0, 3)};
15644
15645 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115646 SequencedSocketData data2(connect2, reads2, writes2);
bnc8016c1f2017-03-31 02:11:2915647 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15648
15649 AddSSLSocketData();
15650
15651 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315652 int rv = session_deps_.host_resolver->LoadIntoCache(
15653 HostPortPair("mail.example.com", 443), base::nullopt);
bnc8016c1f2017-03-31 02:11:2915654 EXPECT_THAT(rv, IsOk());
15655
15656 HttpRequestInfo request1;
15657 request1.method = "GET";
15658 request1.url = GURL("https://www.example.org/");
15659 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015660 request1.traffic_annotation =
15661 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915662 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15663
Eric Orthf4db66a2019-02-19 21:35:3315664 TestCompletionCallback callback;
bnc8016c1f2017-03-31 02:11:2915665 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15666 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15667 rv = callback.WaitForResult();
15668 EXPECT_THAT(rv, IsOk());
15669
15670 const HttpResponseInfo* response = trans1.GetResponseInfo();
15671 ASSERT_TRUE(response);
15672 ASSERT_TRUE(response->headers);
15673 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15674 EXPECT_TRUE(response->was_fetched_via_spdy);
15675 EXPECT_TRUE(response->was_alpn_negotiated);
15676 std::string response_data;
15677 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15678 EXPECT_EQ("hello!", response_data);
15679
15680 HttpRequestInfo request2;
15681 request2.method = "GET";
15682 request2.url = GURL("https://mail.example.org/");
15683 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015684 request2.traffic_annotation =
15685 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915686 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15687
15688 BoundTestNetLog log;
15689 rv = trans2.Start(&request2, callback.callback(), log.bound());
15690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15691 rv = callback.WaitForResult();
15692 EXPECT_THAT(rv, IsOk());
15693
15694 response = trans2.GetResponseInfo();
15695 ASSERT_TRUE(response);
15696 ASSERT_TRUE(response->headers);
15697 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15698 EXPECT_TRUE(response->was_fetched_via_spdy);
15699 EXPECT_TRUE(response->was_alpn_negotiated);
15700 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15701 EXPECT_EQ("hello!", response_data);
15702
15703 TestNetLogEntry::List entries;
15704 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5915705 ExpectLogContainsSomewhere(
15706 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2915707 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5915708}
15709
15710// Test that HTTP 421 responses are properly returned to the caller if received
15711// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
15712// portions of the response.
15713TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
15714 // Two hosts resolve to the same IP address.
15715 const std::string ip_addr = "1.2.3.4";
15716 IPAddress ip;
15717 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15718 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15719
Jeremy Roman0579ed62017-08-29 15:56:1915720 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5915721 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15722 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15723
15724 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15725
15726 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315727 spdy::SpdySerializedFrame req1(
davidbence688ae2017-05-04 15:12:5915728 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15729 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315730 spdy::SpdySerializedFrame req2(
davidbence688ae2017-05-04 15:12:5915731 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315732 spdy::SpdySerializedFrame rst(
15733 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
davidbence688ae2017-05-04 15:12:5915734 MockWrite writes1[] = {
15735 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15736 CreateMockWrite(rst, 6),
15737 };
15738
15739 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315740 spdy::SpdySerializedFrame resp1(
15741 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15742 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15743 spdy::SpdyHeaderBlock response_headers;
15744 response_headers[spdy::kHttp2StatusHeader] = "421";
15745 spdy::SpdySerializedFrame resp2(
davidbence688ae2017-05-04 15:12:5915746 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
15747 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15748 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15749
15750 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115751 SequencedSocketData data1(connect1, reads1, writes1);
davidbence688ae2017-05-04 15:12:5915752 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15753
15754 AddSSLSocketData();
15755
15756 // Retry the second request on a second connection. It returns 421 Misdirected
15757 // Retry again.
15758 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315759 spdy::SpdySerializedFrame req3(
davidbence688ae2017-05-04 15:12:5915760 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15761 MockWrite writes2[] = {
15762 CreateMockWrite(req3, 0),
15763 };
15764
Ryan Hamilton0239aac2018-05-19 00:03:1315765 spdy::SpdySerializedFrame resp3(
davidbence688ae2017-05-04 15:12:5915766 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
Ryan Hamilton0239aac2018-05-19 00:03:1315767 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
davidbence688ae2017-05-04 15:12:5915768 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15769 MockRead(ASYNC, 0, 3)};
15770
15771 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115772 SequencedSocketData data2(connect2, reads2, writes2);
davidbence688ae2017-05-04 15:12:5915773 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15774
15775 AddSSLSocketData();
15776
15777 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315778 int rv = session_deps_.host_resolver->LoadIntoCache(
15779 HostPortPair("mail.example.com", 443), base::nullopt);
davidbence688ae2017-05-04 15:12:5915780 EXPECT_THAT(rv, IsOk());
15781
15782 HttpRequestInfo request1;
15783 request1.method = "GET";
15784 request1.url = GURL("https://www.example.org/");
15785 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015786 request1.traffic_annotation =
15787 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915788 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15789
Eric Orthf4db66a2019-02-19 21:35:3315790 TestCompletionCallback callback;
davidbence688ae2017-05-04 15:12:5915791 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15792 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15793 rv = callback.WaitForResult();
15794 EXPECT_THAT(rv, IsOk());
15795
15796 const HttpResponseInfo* response = trans1.GetResponseInfo();
15797 ASSERT_TRUE(response);
15798 ASSERT_TRUE(response->headers);
15799 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15800 EXPECT_TRUE(response->was_fetched_via_spdy);
15801 EXPECT_TRUE(response->was_alpn_negotiated);
15802 std::string response_data;
15803 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15804 EXPECT_EQ("hello!", response_data);
15805
15806 HttpRequestInfo request2;
15807 request2.method = "GET";
15808 request2.url = GURL("https://mail.example.org/");
15809 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015810 request2.traffic_annotation =
15811 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915812 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15813
15814 BoundTestNetLog log;
15815 rv = trans2.Start(&request2, callback.callback(), log.bound());
15816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15817 rv = callback.WaitForResult();
15818 EXPECT_THAT(rv, IsOk());
15819
15820 // After a retry, the 421 Misdirected Request is reported back up to the
15821 // caller.
15822 response = trans2.GetResponseInfo();
15823 ASSERT_TRUE(response);
15824 ASSERT_TRUE(response->headers);
15825 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
15826 EXPECT_TRUE(response->was_fetched_via_spdy);
15827 EXPECT_TRUE(response->was_alpn_negotiated);
15828 EXPECT_TRUE(response->ssl_info.cert);
15829 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15830 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2915831}
15832
bncd16676a2016-07-20 16:23:0115833TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1315834 UseIPConnectionPoolingWithHostCacheExpiration) {
Eric Orth1da75de2019-02-20 21:10:3415835 // Set up HostResolver to invalidate cached entries after 1 cached resolve.
15836 session_deps_.host_resolver =
15837 std::make_unique<MockCachingHostResolver>(1 /* cache_invalidation_num */);
danakj1fd259a02016-04-16 03:17:0915838 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615839
bnc032658ba2016-09-26 18:17:1515840 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615841
Ryan Hamilton0239aac2018-05-19 00:03:1315842 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915843 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815844 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315845 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715846 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615847 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115848 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615849 };
Ryan Hamilton0239aac2018-05-19 00:03:1315850 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515851 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315852 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115853 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315854 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515855 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315856 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115857 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615858 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115859 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15860 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315861 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615862 };
15863
eroman36d84e54432016-03-17 03:23:0215864 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215865 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115866 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715867 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615868
[email protected]aa22b242011-11-16 18:58:2915869 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615870 HttpRequestInfo request1;
15871 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315872 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615873 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015874 request1.traffic_annotation =
15875 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015876 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615877
tfarina42834112016-09-22 13:38:2015878 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115879 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15880 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615881
15882 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215883 ASSERT_TRUE(response);
15884 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215885 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615886
15887 std::string response_data;
robpercival214763f2016-07-01 23:27:0115888 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615889 EXPECT_EQ("hello!", response_data);
15890
15891 // Preload cache entries into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315892 rv = session_deps_.host_resolver->LoadIntoCache(
15893 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115894 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615895
15896 HttpRequestInfo request2;
15897 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715898 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615899 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015900 request2.traffic_annotation =
15901 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015902 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615903
tfarina42834112016-09-22 13:38:2015904 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115905 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15906 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615907
15908 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215909 ASSERT_TRUE(response);
15910 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215911 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615912 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215913 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115914 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615915 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615916}
15917
bncd16676a2016-07-20 16:23:0115918TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315919 const std::string https_url = "https://www.example.org:8080/";
15920 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415921
15922 // SPDY GET for HTTPS URL
Ryan Hamilton0239aac2018-05-19 00:03:1315923 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915924 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415925
15926 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115927 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415928 };
15929
Raul Tambre94493c652019-03-11 17:18:3515930 spdy::SpdySerializedFrame resp1(
15931 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315932 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4115933 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915934 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415935
Ryan Sleevib8d7ea02018-05-07 20:01:0115936 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415937 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715938 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415939
15940 // HTTP GET for the HTTP URL
15941 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315942 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415943 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315944 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415945 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415946 };
15947
15948 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315949 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15950 MockRead(ASYNC, 2, "hello"),
15951 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415952 };
15953
Ryan Sleevib8d7ea02018-05-07 20:01:0115954 SequencedSocketData data2(reads2, writes2);
[email protected]8450d722012-07-02 19:14:0415955
[email protected]8450d722012-07-02 19:14:0415956 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615957 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715958 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15959 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15960 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415961
danakj1fd259a02016-04-16 03:17:0915962 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415963
15964 // Start the first transaction to set up the SpdySession
15965 HttpRequestInfo request1;
15966 request1.method = "GET";
15967 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415968 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015969 request1.traffic_annotation =
15970 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015971 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415972 TestCompletionCallback callback1;
15973 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015974 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515975 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415976
robpercival214763f2016-07-01 23:27:0115977 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415978 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15979
15980 // Now, start the HTTP request
15981 HttpRequestInfo request2;
15982 request2.method = "GET";
15983 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415984 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015985 request2.traffic_annotation =
15986 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015987 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415988 TestCompletionCallback callback2;
15989 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015990 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515991 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415992
robpercival214763f2016-07-01 23:27:0115993 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415994 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15995}
15996
bnc5452e2a2015-05-08 16:27:4215997// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15998// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115999TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2516000 url::SchemeHostPort server("https", "www.example.org", 443);
16001 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4216002
bnc8bef8da22016-05-30 01:28:2516003 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4216004 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616005 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216006 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16007
16008 // No data should be read from the alternative, because HTTP/1.1 is
16009 // negotiated.
16010 StaticSocketDataProvider data;
16011 session_deps_.socket_factory->AddSocketDataProvider(&data);
16012
16013 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4616014 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4216015 // mocked. This way the request relies on the alternate Job.
16016 StaticSocketDataProvider data_refused;
16017 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16018 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16019
zhongyi3d4a55e72016-04-22 20:36:4616020 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916021 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016022 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216023 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116024 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216025 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116026 http_server_properties->SetHttp2AlternativeService(
16027 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216028
bnc5452e2a2015-05-08 16:27:4216029 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4616030 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216031 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2516032 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e2018-02-07 07:41:1016033 request.traffic_annotation =
16034 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216035 TestCompletionCallback callback;
16036
16037 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5216038 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2016039 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5216040 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4216041}
16042
bnc40448a532015-05-11 19:13:1416043// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4616044// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1416045// succeeds, the request should succeed, even if the latter fails because
16046// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0116047TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2516048 url::SchemeHostPort server("https", "www.example.org", 443);
16049 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1416050
16051 // Negotiate HTTP/1.1 with alternative.
16052 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616053 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416054 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
16055
16056 // No data should be read from the alternative, because HTTP/1.1 is
16057 // negotiated.
16058 StaticSocketDataProvider data;
16059 session_deps_.socket_factory->AddSocketDataProvider(&data);
16060
zhongyi3d4a55e72016-04-22 20:36:4616061 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1416062 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616063 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416064 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
16065
16066 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2516067 MockWrite("GET / HTTP/1.1\r\n"
16068 "Host: www.example.org\r\n"
16069 "Connection: keep-alive\r\n\r\n"),
16070 MockWrite("GET /second HTTP/1.1\r\n"
16071 "Host: www.example.org\r\n"
16072 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1416073 };
16074
16075 MockRead http_reads[] = {
16076 MockRead("HTTP/1.1 200 OK\r\n"),
16077 MockRead("Content-Type: text/html\r\n"),
16078 MockRead("Content-Length: 6\r\n\r\n"),
16079 MockRead("foobar"),
16080 MockRead("HTTP/1.1 200 OK\r\n"),
16081 MockRead("Content-Type: text/html\r\n"),
16082 MockRead("Content-Length: 7\r\n\r\n"),
16083 MockRead("another"),
16084 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116085 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc40448a532015-05-11 19:13:1416086 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16087
zhongyi3d4a55e72016-04-22 20:36:4616088 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916089 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016090 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1416091 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116092 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216093 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116094 http_server_properties->SetHttp2AlternativeService(
16095 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1416096
16097 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
16098 HttpRequestInfo request1;
16099 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2516100 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1416101 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016102 request1.traffic_annotation =
16103 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416104 TestCompletionCallback callback1;
16105
tfarina42834112016-09-22 13:38:2016106 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416107 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116108 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416109
16110 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5216111 ASSERT_TRUE(response1);
16112 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1416113 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
16114
16115 std::string response_data1;
robpercival214763f2016-07-01 23:27:0116116 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1416117 EXPECT_EQ("foobar", response_data1);
16118
16119 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
16120 // for alternative service.
16121 EXPECT_TRUE(
16122 http_server_properties->IsAlternativeServiceBroken(alternative_service));
16123
zhongyi3d4a55e72016-04-22 20:36:4616124 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1416125 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4616126 // to server.
bnc40448a532015-05-11 19:13:1416127 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
16128 HttpRequestInfo request2;
16129 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2516130 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1416131 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016132 request2.traffic_annotation =
16133 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416134 TestCompletionCallback callback2;
16135
tfarina42834112016-09-22 13:38:2016136 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416137 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116138 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416139
16140 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216141 ASSERT_TRUE(response2);
16142 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1416143 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
16144
16145 std::string response_data2;
robpercival214763f2016-07-01 23:27:0116146 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1416147 EXPECT_EQ("another", response_data2);
16148}
16149
bnc5452e2a2015-05-08 16:27:4216150// Alternative service requires HTTP/2 (or SPDY), but there is already a
16151// HTTP/1.1 socket open to the alternative server. That socket should not be
16152// used.
bncd16676a2016-07-20 16:23:0116153TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4616154 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4216155 HostPortPair alternative("alternative.example.org", 443);
16156 std::string origin_url = "https://origin.example.org:443";
16157 std::string alternative_url = "https://alternative.example.org:443";
16158
16159 // Negotiate HTTP/1.1 with alternative.example.org.
16160 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616161 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216162 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16163
16164 // HTTP/1.1 data for |request1| and |request2|.
16165 MockWrite http_writes[] = {
16166 MockWrite(
16167 "GET / HTTP/1.1\r\n"
16168 "Host: alternative.example.org\r\n"
16169 "Connection: keep-alive\r\n\r\n"),
16170 MockWrite(
16171 "GET / HTTP/1.1\r\n"
16172 "Host: alternative.example.org\r\n"
16173 "Connection: keep-alive\r\n\r\n"),
16174 };
16175
16176 MockRead http_reads[] = {
16177 MockRead(
16178 "HTTP/1.1 200 OK\r\n"
16179 "Content-Type: text/html; charset=iso-8859-1\r\n"
16180 "Content-Length: 40\r\n\r\n"
16181 "first HTTP/1.1 response from alternative"),
16182 MockRead(
16183 "HTTP/1.1 200 OK\r\n"
16184 "Content-Type: text/html; charset=iso-8859-1\r\n"
16185 "Content-Length: 41\r\n\r\n"
16186 "second HTTP/1.1 response from alternative"),
16187 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116188 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc5452e2a2015-05-08 16:27:4216189 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16190
16191 // This test documents that an alternate Job should not pool to an already
16192 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4616193 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4216194 StaticSocketDataProvider data_refused;
16195 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16196 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16197
zhongyi3d4a55e72016-04-22 20:36:4616198 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916199 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016200 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216201 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116202 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216203 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116204 http_server_properties->SetHttp2AlternativeService(
16205 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216206
16207 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4216208 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4616209 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216210 request1.method = "GET";
16211 request1.url = GURL(alternative_url);
16212 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016213 request1.traffic_annotation =
16214 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216215 TestCompletionCallback callback1;
16216
tfarina42834112016-09-22 13:38:2016217 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116218 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616219 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216220 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5216221 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4216222 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216223 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216224 EXPECT_FALSE(response1->was_fetched_via_spdy);
16225 std::string response_data1;
bnc691fda62016-08-12 00:43:1616226 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4216227 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
16228
16229 // Request for origin.example.org, which has an alternative service. This
16230 // will start two Jobs: the alternative looks for connections to pool to,
16231 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4616232 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4216233 // this request fails.
bnc5452e2a2015-05-08 16:27:4216234 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4616235 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216236 request2.method = "GET";
16237 request2.url = GURL(origin_url);
16238 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016239 request2.traffic_annotation =
16240 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216241 TestCompletionCallback callback2;
16242
tfarina42834112016-09-22 13:38:2016243 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116244 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4216245
16246 // Another transaction to alternative. This is to test that the HTTP/1.1
16247 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4216248 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4616249 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216250 request3.method = "GET";
16251 request3.url = GURL(alternative_url);
16252 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016253 request3.traffic_annotation =
16254 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216255 TestCompletionCallback callback3;
16256
tfarina42834112016-09-22 13:38:2016257 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116258 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616259 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216260 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5216261 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4216262 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216263 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216264 EXPECT_FALSE(response3->was_fetched_via_spdy);
16265 std::string response_data3;
bnc691fda62016-08-12 00:43:1616266 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4216267 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
16268}
16269
bncd16676a2016-07-20 16:23:0116270TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2316271 const std::string https_url = "https://www.example.org:8080/";
16272 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0416273
rdsmithebb50aa2015-11-12 03:44:3816274 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0116275 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3816276
[email protected]8450d722012-07-02 19:14:0416277 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2316278 const HostPortPair host_port_pair("www.example.org", 8080);
Matt Menke6e879bd2019-03-18 17:26:0416279 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
16280 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
16281 host_port_pair));
Ryan Hamilton0239aac2018-05-19 00:03:1316282 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4916283 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1316284 spdy::SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0216285 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3916286
16287 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
Ryan Hamilton0239aac2018-05-19 00:03:1316288 spdy::SpdyHeaderBlock req2_block;
16289 req2_block[spdy::kHttp2MethodHeader] = "GET";
16290 req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
16291 req2_block[spdy::kHttp2SchemeHeader] = "http";
16292 req2_block[spdy::kHttp2PathHeader] = "/";
16293 spdy::SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1516294 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0416295
16296 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116297 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
16298 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0416299 };
16300
Ryan Hamilton0239aac2018-05-19 00:03:1316301 spdy::SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1516302 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316303 spdy::SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1516304 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316305 spdy::SpdySerializedFrame body1(
16306 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
16307 spdy::SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3816308 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316309 spdy::SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3816310 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
Raul Tambre94493c652019-03-11 17:18:3516311 spdy::SpdySerializedFrame resp2(
16312 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1316313 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3316314 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116315 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3316316 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4116317 CreateMockRead(wrapped_resp1, 4),
16318 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3316319 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4116320 CreateMockRead(resp2, 8),
16321 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3316322 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
16323 };
[email protected]8450d722012-07-02 19:14:0416324
Ryan Sleevib8d7ea02018-05-07 20:01:0116325 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0416326 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5716327 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0416328
Lily Houghton8c2f97d2018-01-22 05:06:5916329 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916330 ProxyResolutionService::CreateFixedFromPacResult(
16331 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5116332 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0716333 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0416334 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616335 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316336 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0416337 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616338 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316339 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16340 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0416341
danakj1fd259a02016-04-16 03:17:0916342 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0416343
16344 // Start the first transaction to set up the SpdySession
16345 HttpRequestInfo request1;
16346 request1.method = "GET";
16347 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0416348 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016349 request1.traffic_annotation =
16350 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016351 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0416352 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2016353 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416354
mmenke666a6fea2015-12-19 04:16:3316355 // This pause is a hack to avoid running into https://crbug.com/497228.
16356 data1.RunUntilPaused();
16357 base::RunLoop().RunUntilIdle();
16358 data1.Resume();
robpercival214763f2016-07-01 23:27:0116359 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0416360 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16361
[email protected]f6c63db52013-02-02 00:35:2216362 LoadTimingInfo load_timing_info1;
16363 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
16364 TestLoadTimingNotReusedWithPac(load_timing_info1,
16365 CONNECT_TIMING_HAS_SSL_TIMES);
16366
mmenke666a6fea2015-12-19 04:16:3316367 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0416368 HttpRequestInfo request2;
16369 request2.method = "GET";
16370 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0416371 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016372 request2.traffic_annotation =
16373 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016374 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0416375 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2016376 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416377
mmenke666a6fea2015-12-19 04:16:3316378 // This pause is a hack to avoid running into https://crbug.com/497228.
16379 data1.RunUntilPaused();
16380 base::RunLoop().RunUntilIdle();
16381 data1.Resume();
robpercival214763f2016-07-01 23:27:0116382 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3316383
[email protected]8450d722012-07-02 19:14:0416384 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2216385
16386 LoadTimingInfo load_timing_info2;
16387 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
16388 // The established SPDY sessions is considered reused by the HTTP request.
16389 TestLoadTimingReusedWithPac(load_timing_info2);
16390 // HTTP requests over a SPDY session should have a different connection
16391 // socket_log_id than requests over a tunnel.
16392 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0416393}
16394
[email protected]2d88e7d2012-07-19 17:55:1716395// Test that in the case where we have a SPDY session to a SPDY proxy
16396// that we do not pool other origins that resolve to the same IP when
16397// the certificate does not match the new origin.
16398// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0116399TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2316400 const std::string url1 = "http://www.example.org/";
16401 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1716402 const std::string ip_addr = "1.2.3.4";
16403
rdsmithebb50aa2015-11-12 03:44:3816404 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0116405 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3816406
[email protected]2d88e7d2012-07-19 17:55:1716407 // SPDY GET for HTTP URL (through SPDY proxy)
Ryan Hamilton0239aac2018-05-19 00:03:1316408 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2316409 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:1316410 spdy::SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1516411 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1716412
16413 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116414 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1716415 };
16416
Raul Tambre94493c652019-03-11 17:18:3516417 spdy::SpdySerializedFrame resp1(
16418 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316419 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1716420 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116421 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
16422 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1716423 };
16424
Ryan Sleevib8d7ea02018-05-07 20:01:0116425 SequencedSocketData data1(reads1, writes1);
martijnfe9636e2016-02-06 14:33:3216426 IPAddress ip;
martijn654c8c42016-02-10 22:10:5916427 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1716428 IPEndPoint peer_addr = IPEndPoint(ip, 443);
16429 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3316430 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1716431
16432 // SPDY GET for HTTPS URL (direct)
Ryan Hamilton0239aac2018-05-19 00:03:1316433 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916434 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1716435
16436 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116437 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1716438 };
16439
Ryan Hamilton0239aac2018-05-19 00:03:1316440 spdy::SpdySerializedFrame resp2(
Raul Tambre94493c652019-03-11 17:18:3516441 spdy_util_secure.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316442 spdy::SpdySerializedFrame body2(
16443 spdy_util_secure.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4116444 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3316445 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1716446
Ryan Sleevib8d7ea02018-05-07 20:01:0116447 SequencedSocketData data2(reads2, writes2);
[email protected]2d88e7d2012-07-19 17:55:1716448 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3316449 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1716450
16451 // Set up a proxy config that sends HTTP requests to a proxy, and
16452 // all others direct.
16453 ProxyConfig proxy_config;
16454 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4916455 session_deps_.proxy_resolution_service =
16456 std::make_unique<ProxyResolutionService>(
16457 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
16458 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
16459 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1716460
bncce36dca22015-04-21 22:11:2316461 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616462 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1716463 // Load a valid cert. Note, that this does not need to
16464 // be valid for proxy because the MockSSLClientSocket does
16465 // not actually verify it. But SpdySession will use this
16466 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4916467 ssl1.ssl_info.cert =
16468 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
16469 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3316470 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16471 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1716472
16473 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616474 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316475 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16476 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1716477
Jeremy Roman0579ed62017-08-29 15:56:1916478 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2316479 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0716480 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1716481
danakj1fd259a02016-04-16 03:17:0916482 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1716483
16484 // Start the first transaction to set up the SpdySession
16485 HttpRequestInfo request1;
16486 request1.method = "GET";
16487 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1716488 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016489 request1.traffic_annotation =
16490 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016491 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716492 TestCompletionCallback callback1;
16493 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016494 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3316495 // This pause is a hack to avoid running into https://crbug.com/497228.
16496 data1.RunUntilPaused();
16497 base::RunLoop().RunUntilIdle();
16498 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1716499
robpercival214763f2016-07-01 23:27:0116500 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716501 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16502
16503 // Now, start the HTTP request
16504 HttpRequestInfo request2;
16505 request2.method = "GET";
16506 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1716507 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016508 request2.traffic_annotation =
16509 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016510 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716511 TestCompletionCallback callback2;
16512 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016513 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516514 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1716515
16516 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0116517 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716518 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16519}
16520
[email protected]85f97342013-04-17 06:12:2416521// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
16522// error) in SPDY session, removes the socket from pool and closes the SPDY
16523// session. Verify that new url's from the same HttpNetworkSession (and a new
16524// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0116525TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2316526 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2416527
16528 MockRead reads1[] = {
16529 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
16530 };
16531
Ryan Sleevib8d7ea02018-05-07 20:01:0116532 SequencedSocketData data1(reads1, base::span<MockWrite>());
[email protected]85f97342013-04-17 06:12:2416533
Ryan Hamilton0239aac2018-05-19 00:03:1316534 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916535 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2416536 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116537 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2416538 };
16539
Raul Tambre94493c652019-03-11 17:18:3516540 spdy::SpdySerializedFrame resp2(
16541 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316542 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2416543 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4116544 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
16545 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2416546 };
16547
Ryan Sleevib8d7ea02018-05-07 20:01:0116548 SequencedSocketData data2(reads2, writes2);
[email protected]85f97342013-04-17 06:12:2416549
[email protected]85f97342013-04-17 06:12:2416550 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616551 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016552 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16553 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2416554
16555 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616556 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016557 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16558 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2416559
danakj1fd259a02016-04-16 03:17:0916560 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5016561 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2416562
16563 // Start the first transaction to set up the SpdySession and verify that
16564 // connection was closed.
16565 HttpRequestInfo request1;
16566 request1.method = "GET";
16567 request1.url = GURL(https_url);
16568 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016569 request1.traffic_annotation =
16570 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016571 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416572 TestCompletionCallback callback1;
16573 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016574 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116575 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2416576
16577 // Now, start the second request and make sure it succeeds.
16578 HttpRequestInfo request2;
16579 request2.method = "GET";
16580 request2.url = GURL(https_url);
16581 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016582 request2.traffic_annotation =
16583 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016584 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416585 TestCompletionCallback callback2;
16586 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016587 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2416588
robpercival214763f2016-07-01 23:27:0116589 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2416590 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16591}
16592
bncd16676a2016-07-20 16:23:0116593TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0316594 ClientSocketPoolManager::set_max_sockets_per_group(
16595 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16596 ClientSocketPoolManager::set_max_sockets_per_pool(
16597 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16598
16599 // Use two different hosts with different IPs so they don't get pooled.
16600 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
16601 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0916602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0316603
16604 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616605 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316606 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616607 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316608 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16609 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16610
Ryan Hamilton0239aac2018-05-19 00:03:1316611 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4916612 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316613 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116614 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0316615 };
Ryan Hamilton0239aac2018-05-19 00:03:1316616 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3516617 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316618 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4116619 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316620 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116621 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916622 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316623 };
16624
rdsmithebb50aa2015-11-12 03:44:3816625 // Use a separate test instance for the separate SpdySession that will be
16626 // created.
bncd16676a2016-07-20 16:23:0116627 SpdyTestUtil spdy_util_2;
Ryan Sleevib8d7ea02018-05-07 20:01:0116628 SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
Bence Béky53a5aef2018-03-29 21:54:1216629 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0316630
Ryan Hamilton0239aac2018-05-19 00:03:1316631 spdy::SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4916632 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316633 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116634 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0316635 };
Ryan Hamilton0239aac2018-05-19 00:03:1316636 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3516637 spdy_util_2.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316638 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4116639 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316640 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116641 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916642 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316643 };
16644
Ryan Sleevib8d7ea02018-05-07 20:01:0116645 SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
Bence Béky53a5aef2018-03-29 21:54:1216646 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0316647
16648 MockWrite http_write[] = {
16649 MockWrite("GET / HTTP/1.1\r\n"
16650 "Host: www.a.com\r\n"
16651 "Connection: keep-alive\r\n\r\n"),
16652 };
16653
16654 MockRead http_read[] = {
16655 MockRead("HTTP/1.1 200 OK\r\n"),
16656 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16657 MockRead("Content-Length: 6\r\n\r\n"),
16658 MockRead("hello!"),
16659 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116660 StaticSocketDataProvider http_data(http_read, http_write);
[email protected]483fa202013-05-14 01:07:0316661 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16662
16663 HostPortPair host_port_pair_a("www.a.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116664 SpdySessionKey spdy_session_key_a(
16665 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16666 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316667 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616668 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316669
16670 TestCompletionCallback callback;
16671 HttpRequestInfo request1;
16672 request1.method = "GET";
16673 request1.url = GURL("https://www.a.com/");
16674 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016675 request1.traffic_annotation =
16676 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816677 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916678 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316679
tfarina42834112016-09-22 13:38:2016680 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116681 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16682 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316683
16684 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216685 ASSERT_TRUE(response);
16686 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216687 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316688 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216689 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0316690
16691 std::string response_data;
robpercival214763f2016-07-01 23:27:0116692 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316693 EXPECT_EQ("hello!", response_data);
16694 trans.reset();
16695 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616696 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316697
16698 HostPortPair host_port_pair_b("www.b.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116699 SpdySessionKey spdy_session_key_b(
16700 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16701 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316702 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616703 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316704 HttpRequestInfo request2;
16705 request2.method = "GET";
16706 request2.url = GURL("https://www.b.com/");
16707 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016708 request2.traffic_annotation =
16709 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816710 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916711 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316712
tfarina42834112016-09-22 13:38:2016713 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116714 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16715 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316716
16717 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216718 ASSERT_TRUE(response);
16719 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216720 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316721 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216722 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116723 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316724 EXPECT_EQ("hello!", response_data);
16725 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616726 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316727 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616728 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316729
16730 HostPortPair host_port_pair_a1("www.a.com", 80);
Matt Menke2436b2f2018-12-11 18:07:1116731 SpdySessionKey spdy_session_key_a1(
16732 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16733 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316734 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616735 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0316736 HttpRequestInfo request3;
16737 request3.method = "GET";
16738 request3.url = GURL("http://www.a.com/");
16739 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016740 request3.traffic_annotation =
16741 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816742 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916743 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316744
tfarina42834112016-09-22 13:38:2016745 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116746 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16747 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316748
16749 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216750 ASSERT_TRUE(response);
16751 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0316752 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16753 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216754 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116755 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316756 EXPECT_EQ("hello!", response_data);
16757 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616758 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316759 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616760 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316761}
16762
bncd16676a2016-07-20 16:23:0116763TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416764 HttpRequestInfo request;
16765 request.method = "GET";
bncce36dca22015-04-21 22:11:2316766 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016767 request.traffic_annotation =
16768 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416769
danakj1fd259a02016-04-16 03:17:0916770 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616771 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416772
ttuttled9dbc652015-09-29 20:00:5916773 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416774 StaticSocketDataProvider data;
16775 data.set_connect_data(mock_connect);
16776 session_deps_.socket_factory->AddSocketDataProvider(&data);
16777
16778 TestCompletionCallback callback;
16779
tfarina42834112016-09-22 13:38:2016780 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116781 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416782
16783 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116784 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416785
[email protected]79e1fd62013-06-20 06:50:0416786 // We don't care whether this succeeds or fails, but it shouldn't crash.
16787 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616788 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716789
16790 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616791 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716792 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116793 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916794
16795 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616796 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916797 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416798}
16799
bncd16676a2016-07-20 16:23:0116800TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416801 HttpRequestInfo request;
16802 request.method = "GET";
bncce36dca22015-04-21 22:11:2316803 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016804 request.traffic_annotation =
16805 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416806
danakj1fd259a02016-04-16 03:17:0916807 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616808 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416809
ttuttled9dbc652015-09-29 20:00:5916810 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416811 StaticSocketDataProvider data;
16812 data.set_connect_data(mock_connect);
16813 session_deps_.socket_factory->AddSocketDataProvider(&data);
16814
16815 TestCompletionCallback callback;
16816
tfarina42834112016-09-22 13:38:2016817 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416819
16820 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116821 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416822
[email protected]79e1fd62013-06-20 06:50:0416823 // We don't care whether this succeeds or fails, but it shouldn't crash.
16824 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616825 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716826
16827 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616828 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716829 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116830 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916831
16832 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616833 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916834 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416835}
16836
bncd16676a2016-07-20 16:23:0116837TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416838 HttpRequestInfo request;
16839 request.method = "GET";
bncce36dca22015-04-21 22:11:2316840 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016841 request.traffic_annotation =
16842 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416843
danakj1fd259a02016-04-16 03:17:0916844 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616845 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416846
16847 MockWrite data_writes[] = {
16848 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16849 };
16850 MockRead data_reads[] = {
16851 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16852 };
16853
Ryan Sleevib8d7ea02018-05-07 20:01:0116854 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416855 session_deps_.socket_factory->AddSocketDataProvider(&data);
16856
16857 TestCompletionCallback callback;
16858
tfarina42834112016-09-22 13:38:2016859 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116860 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416861
16862 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116863 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416864
[email protected]79e1fd62013-06-20 06:50:0416865 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616866 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416867 EXPECT_TRUE(request_headers.HasHeader("Host"));
16868}
16869
bncd16676a2016-07-20 16:23:0116870TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416871 HttpRequestInfo request;
16872 request.method = "GET";
bncce36dca22015-04-21 22:11:2316873 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016874 request.traffic_annotation =
16875 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416876
danakj1fd259a02016-04-16 03:17:0916877 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616878 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416879
16880 MockWrite data_writes[] = {
16881 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16882 };
16883 MockRead data_reads[] = {
16884 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16885 };
16886
Ryan Sleevib8d7ea02018-05-07 20:01:0116887 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416888 session_deps_.socket_factory->AddSocketDataProvider(&data);
16889
16890 TestCompletionCallback callback;
16891
tfarina42834112016-09-22 13:38:2016892 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416894
16895 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116896 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416897
[email protected]79e1fd62013-06-20 06:50:0416898 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616899 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416900 EXPECT_TRUE(request_headers.HasHeader("Host"));
16901}
16902
bncd16676a2016-07-20 16:23:0116903TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416904 HttpRequestInfo request;
16905 request.method = "GET";
bncce36dca22015-04-21 22:11:2316906 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016907 request.traffic_annotation =
16908 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416909
danakj1fd259a02016-04-16 03:17:0916910 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616911 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416912
16913 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316914 MockWrite(
16915 "GET / HTTP/1.1\r\n"
16916 "Host: www.example.org\r\n"
16917 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416918 };
16919 MockRead data_reads[] = {
16920 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16921 };
16922
Ryan Sleevib8d7ea02018-05-07 20:01:0116923 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416924 session_deps_.socket_factory->AddSocketDataProvider(&data);
16925
16926 TestCompletionCallback callback;
16927
tfarina42834112016-09-22 13:38:2016928 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116929 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416930
16931 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116932 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416933
[email protected]79e1fd62013-06-20 06:50:0416934 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616935 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416936 EXPECT_TRUE(request_headers.HasHeader("Host"));
16937}
16938
bncd16676a2016-07-20 16:23:0116939TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416940 HttpRequestInfo request;
16941 request.method = "GET";
bncce36dca22015-04-21 22:11:2316942 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016943 request.traffic_annotation =
16944 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416945
danakj1fd259a02016-04-16 03:17:0916946 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616947 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416948
16949 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316950 MockWrite(
16951 "GET / HTTP/1.1\r\n"
16952 "Host: www.example.org\r\n"
16953 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416954 };
16955 MockRead data_reads[] = {
16956 MockRead(ASYNC, ERR_CONNECTION_RESET),
16957 };
16958
Ryan Sleevib8d7ea02018-05-07 20:01:0116959 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416960 session_deps_.socket_factory->AddSocketDataProvider(&data);
16961
16962 TestCompletionCallback callback;
16963
tfarina42834112016-09-22 13:38:2016964 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116965 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416966
16967 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116968 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416969
[email protected]79e1fd62013-06-20 06:50:0416970 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616971 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416972 EXPECT_TRUE(request_headers.HasHeader("Host"));
16973}
16974
bncd16676a2016-07-20 16:23:0116975TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416976 HttpRequestInfo request;
16977 request.method = "GET";
bncce36dca22015-04-21 22:11:2316978 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416979 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1016980 request.traffic_annotation =
16981 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416982
danakj1fd259a02016-04-16 03:17:0916983 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616984 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416985
16986 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316987 MockWrite(
16988 "GET / HTTP/1.1\r\n"
16989 "Host: www.example.org\r\n"
16990 "Connection: keep-alive\r\n"
16991 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416992 };
16993 MockRead data_reads[] = {
16994 MockRead("HTTP/1.1 200 OK\r\n"
16995 "Content-Length: 5\r\n\r\n"
16996 "hello"),
16997 MockRead(ASYNC, ERR_UNEXPECTED),
16998 };
16999
Ryan Sleevib8d7ea02018-05-07 20:01:0117000 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0417001 session_deps_.socket_factory->AddSocketDataProvider(&data);
17002
17003 TestCompletionCallback callback;
17004
tfarina42834112016-09-22 13:38:2017005 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117006 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0417007
17008 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117009 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0417010
17011 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1617012 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0417013 std::string foo;
17014 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
17015 EXPECT_EQ("bar", foo);
17016}
17017
[email protected]043b68c82013-08-22 23:41:5217018// Tests that when a used socket is returned to the SSL socket pool, it's closed
17019// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117020TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5217021 ClientSocketPoolManager::set_max_sockets_per_group(
17022 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17023 ClientSocketPoolManager::set_max_sockets_per_pool(
17024 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17025
17026 // Set up SSL request.
17027
17028 HttpRequestInfo ssl_request;
17029 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2317030 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017031 ssl_request.traffic_annotation =
17032 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217033
17034 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2317035 MockWrite(
17036 "GET / HTTP/1.1\r\n"
17037 "Host: www.example.org\r\n"
17038 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217039 };
17040 MockRead ssl_reads[] = {
17041 MockRead("HTTP/1.1 200 OK\r\n"),
17042 MockRead("Content-Length: 11\r\n\r\n"),
17043 MockRead("hello world"),
17044 MockRead(SYNCHRONOUS, OK),
17045 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117046 StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
[email protected]043b68c82013-08-22 23:41:5217047 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17048
17049 SSLSocketDataProvider ssl(ASYNC, OK);
17050 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17051
17052 // Set up HTTP request.
17053
17054 HttpRequestInfo http_request;
17055 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317056 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017057 http_request.traffic_annotation =
17058 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217059
17060 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317061 MockWrite(
17062 "GET / HTTP/1.1\r\n"
17063 "Host: www.example.org\r\n"
17064 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217065 };
17066 MockRead http_reads[] = {
17067 MockRead("HTTP/1.1 200 OK\r\n"),
17068 MockRead("Content-Length: 7\r\n\r\n"),
17069 MockRead("falafel"),
17070 MockRead(SYNCHRONOUS, OK),
17071 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117072 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217073 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17074
danakj1fd259a02016-04-16 03:17:0917075 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217076
17077 // Start the SSL request.
17078 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1617079 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017080 ASSERT_EQ(ERR_IO_PENDING,
17081 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
17082 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5217083
17084 // Start the HTTP request. Pool should stall.
17085 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617086 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017087 ASSERT_EQ(ERR_IO_PENDING,
17088 http_trans.Start(&http_request, http_callback.callback(),
17089 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117090 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217091
17092 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0117093 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217094 std::string response_data;
bnc691fda62016-08-12 00:43:1617095 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217096 EXPECT_EQ("hello world", response_data);
17097
17098 // The SSL socket should automatically be closed, so the HTTP request can
17099 // start.
Matt Menke9d5e2c92019-02-05 01:42:2317100 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
dcheng48459ac22014-08-26 00:46:4117101 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217102
17103 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0117104 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1617105 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217106 EXPECT_EQ("falafel", response_data);
17107
dcheng48459ac22014-08-26 00:46:4117108 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217109}
17110
17111// Tests that when a SSL connection is established but there's no corresponding
17112// request that needs it, the new socket is closed if the transport socket pool
17113// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117114TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5217115 ClientSocketPoolManager::set_max_sockets_per_group(
17116 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17117 ClientSocketPoolManager::set_max_sockets_per_pool(
17118 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17119
17120 // Set up an ssl request.
17121
17122 HttpRequestInfo ssl_request;
17123 ssl_request.method = "GET";
17124 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1017125 ssl_request.traffic_annotation =
17126 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217127
17128 // No data will be sent on the SSL socket.
17129 StaticSocketDataProvider ssl_data;
17130 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17131
17132 SSLSocketDataProvider ssl(ASYNC, OK);
17133 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17134
17135 // Set up HTTP request.
17136
17137 HttpRequestInfo http_request;
17138 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317139 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017140 http_request.traffic_annotation =
17141 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217142
17143 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317144 MockWrite(
17145 "GET / HTTP/1.1\r\n"
17146 "Host: www.example.org\r\n"
17147 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217148 };
17149 MockRead http_reads[] = {
17150 MockRead("HTTP/1.1 200 OK\r\n"),
17151 MockRead("Content-Length: 7\r\n\r\n"),
17152 MockRead("falafel"),
17153 MockRead(SYNCHRONOUS, OK),
17154 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117155 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217156 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17157
danakj1fd259a02016-04-16 03:17:0917158 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217159
17160 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
17161 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2917162 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5917163 http_stream_factory->PreconnectStreams(1, ssl_request);
Matt Menke9d5e2c92019-02-05 01:42:2317164 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217165
17166 // Start the HTTP request. Pool should stall.
17167 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617168 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017169 ASSERT_EQ(ERR_IO_PENDING,
17170 http_trans.Start(&http_request, http_callback.callback(),
17171 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117172 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217173
17174 // The SSL connection will automatically be closed once the connection is
17175 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0117176 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217177 std::string response_data;
bnc691fda62016-08-12 00:43:1617178 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217179 EXPECT_EQ("falafel", response_data);
17180
dcheng48459ac22014-08-26 00:46:4117181 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217182}
17183
bncd16676a2016-07-20 16:23:0117184TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917185 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217186 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917187 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217188 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417189
17190 HttpRequestInfo request;
17191 request.method = "POST";
17192 request.url = GURL("http://www.foo.com/");
17193 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017194 request.traffic_annotation =
17195 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417196
danakj1fd259a02016-04-16 03:17:0917197 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617198 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417199 // Send headers successfully, but get an error while sending the body.
17200 MockWrite data_writes[] = {
17201 MockWrite("POST / HTTP/1.1\r\n"
17202 "Host: www.foo.com\r\n"
17203 "Connection: keep-alive\r\n"
17204 "Content-Length: 3\r\n\r\n"),
17205 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17206 };
17207
17208 MockRead data_reads[] = {
17209 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17210 MockRead("hello world"),
17211 MockRead(SYNCHRONOUS, OK),
17212 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117213 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417214 session_deps_.socket_factory->AddSocketDataProvider(&data);
17215
17216 TestCompletionCallback callback;
17217
tfarina42834112016-09-22 13:38:2017218 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117219 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417220
17221 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117222 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417223
bnc691fda62016-08-12 00:43:1617224 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217225 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417226
wezca1070932016-05-26 20:30:5217227 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417228 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17229
17230 std::string response_data;
bnc691fda62016-08-12 00:43:1617231 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117232 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417233 EXPECT_EQ("hello world", response_data);
17234}
17235
17236// This test makes sure the retry logic doesn't trigger when reading an error
17237// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0117238TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417239 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0917240 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5417241 MockWrite data_writes[] = {
17242 MockWrite("GET / HTTP/1.1\r\n"
17243 "Host: www.foo.com\r\n"
17244 "Connection: keep-alive\r\n\r\n"),
17245 MockWrite("POST / HTTP/1.1\r\n"
17246 "Host: www.foo.com\r\n"
17247 "Connection: keep-alive\r\n"
17248 "Content-Length: 3\r\n\r\n"),
17249 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17250 };
17251
17252 MockRead data_reads[] = {
17253 MockRead("HTTP/1.1 200 Peachy\r\n"
17254 "Content-Length: 14\r\n\r\n"),
17255 MockRead("first response"),
17256 MockRead("HTTP/1.1 400 Not OK\r\n"
17257 "Content-Length: 15\r\n\r\n"),
17258 MockRead("second response"),
17259 MockRead(SYNCHRONOUS, OK),
17260 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117261 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417262 session_deps_.socket_factory->AddSocketDataProvider(&data);
17263
17264 TestCompletionCallback callback;
17265 HttpRequestInfo request1;
17266 request1.method = "GET";
17267 request1.url = GURL("http://www.foo.com/");
17268 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1017269 request1.traffic_annotation =
17270 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417271
bnc87dcefc2017-05-25 12:47:5817272 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1917273 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017274 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117275 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417276
17277 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117278 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417279
17280 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5217281 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5417282
wezca1070932016-05-26 20:30:5217283 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5417284 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
17285
17286 std::string response_data1;
17287 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0117288 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417289 EXPECT_EQ("first response", response_data1);
17290 // Delete the transaction to release the socket back into the socket pool.
17291 trans1.reset();
17292
danakj1fd259a02016-04-16 03:17:0917293 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217294 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917295 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217296 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417297
17298 HttpRequestInfo request2;
17299 request2.method = "POST";
17300 request2.url = GURL("http://www.foo.com/");
17301 request2.upload_data_stream = &upload_data_stream;
17302 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1017303 request2.traffic_annotation =
17304 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417305
bnc691fda62016-08-12 00:43:1617306 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017307 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117308 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417309
17310 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117311 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417312
bnc691fda62016-08-12 00:43:1617313 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5217314 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5417315
wezca1070932016-05-26 20:30:5217316 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5417317 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
17318
17319 std::string response_data2;
bnc691fda62016-08-12 00:43:1617320 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0117321 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417322 EXPECT_EQ("second response", response_data2);
17323}
17324
bncd16676a2016-07-20 16:23:0117325TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417326 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0917327 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217328 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917329 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217330 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417331
17332 HttpRequestInfo request;
17333 request.method = "POST";
17334 request.url = GURL("http://www.foo.com/");
17335 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017336 request.traffic_annotation =
17337 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417338
danakj1fd259a02016-04-16 03:17:0917339 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617340 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417341 // Send headers successfully, but get an error while sending the body.
17342 MockWrite data_writes[] = {
17343 MockWrite("POST / HTTP/1.1\r\n"
17344 "Host: www.foo.com\r\n"
17345 "Connection: keep-alive\r\n"
17346 "Content-Length: 3\r\n\r\n"
17347 "fo"),
17348 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17349 };
17350
17351 MockRead data_reads[] = {
17352 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17353 MockRead("hello world"),
17354 MockRead(SYNCHRONOUS, OK),
17355 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117356 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417357 session_deps_.socket_factory->AddSocketDataProvider(&data);
17358
17359 TestCompletionCallback callback;
17360
tfarina42834112016-09-22 13:38:2017361 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117362 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417363
17364 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117365 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417366
bnc691fda62016-08-12 00:43:1617367 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217368 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417369
wezca1070932016-05-26 20:30:5217370 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417371 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17372
17373 std::string response_data;
bnc691fda62016-08-12 00:43:1617374 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117375 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417376 EXPECT_EQ("hello world", response_data);
17377}
17378
17379// This tests the more common case than the previous test, where headers and
17380// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0117381TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0717382 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5417383
17384 HttpRequestInfo request;
17385 request.method = "POST";
17386 request.url = GURL("http://www.foo.com/");
17387 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017388 request.traffic_annotation =
17389 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417390
danakj1fd259a02016-04-16 03:17:0917391 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617392 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417393 // Send headers successfully, but get an error while sending the body.
17394 MockWrite data_writes[] = {
17395 MockWrite("POST / HTTP/1.1\r\n"
17396 "Host: www.foo.com\r\n"
17397 "Connection: keep-alive\r\n"
17398 "Transfer-Encoding: chunked\r\n\r\n"),
17399 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17400 };
17401
17402 MockRead data_reads[] = {
17403 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17404 MockRead("hello world"),
17405 MockRead(SYNCHRONOUS, OK),
17406 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117407 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417408 session_deps_.socket_factory->AddSocketDataProvider(&data);
17409
17410 TestCompletionCallback callback;
17411
tfarina42834112016-09-22 13:38:2017412 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117413 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417414 // Make sure the headers are sent before adding a chunk. This ensures that
17415 // they can't be merged with the body in a single send. Not currently
17416 // necessary since a chunked body is never merged with headers, but this makes
17417 // the test more future proof.
17418 base::RunLoop().RunUntilIdle();
17419
mmenkecbc2b712014-10-09 20:29:0717420 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5417421
17422 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117423 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417424
bnc691fda62016-08-12 00:43:1617425 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217426 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417427
wezca1070932016-05-26 20:30:5217428 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417429 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17430
17431 std::string response_data;
bnc691fda62016-08-12 00:43:1617432 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117433 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417434 EXPECT_EQ("hello world", response_data);
17435}
17436
bncd16676a2016-07-20 16:23:0117437TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917438 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217439 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917440 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217441 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417442
17443 HttpRequestInfo request;
17444 request.method = "POST";
17445 request.url = GURL("http://www.foo.com/");
17446 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017447 request.traffic_annotation =
17448 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417449
danakj1fd259a02016-04-16 03:17:0917450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617451 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417452
17453 MockWrite data_writes[] = {
17454 MockWrite("POST / HTTP/1.1\r\n"
17455 "Host: www.foo.com\r\n"
17456 "Connection: keep-alive\r\n"
17457 "Content-Length: 3\r\n\r\n"),
17458 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17459 };
17460
17461 MockRead data_reads[] = {
17462 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17463 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17464 MockRead("hello world"),
17465 MockRead(SYNCHRONOUS, OK),
17466 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117467 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417468 session_deps_.socket_factory->AddSocketDataProvider(&data);
17469
17470 TestCompletionCallback callback;
17471
tfarina42834112016-09-22 13:38:2017472 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117473 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417474
17475 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117476 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417477
bnc691fda62016-08-12 00:43:1617478 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217479 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417480
wezca1070932016-05-26 20:30:5217481 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417482 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17483
17484 std::string response_data;
bnc691fda62016-08-12 00:43:1617485 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117486 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417487 EXPECT_EQ("hello world", response_data);
17488}
17489
bncd16676a2016-07-20 16:23:0117490TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917491 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217492 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917493 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217494 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417495
17496 HttpRequestInfo request;
17497 request.method = "POST";
17498 request.url = GURL("http://www.foo.com/");
17499 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017500 request.traffic_annotation =
17501 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417502
danakj1fd259a02016-04-16 03:17:0917503 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617504 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417505 // Send headers successfully, but get an error while sending the body.
17506 MockWrite data_writes[] = {
17507 MockWrite("POST / HTTP/1.1\r\n"
17508 "Host: www.foo.com\r\n"
17509 "Connection: keep-alive\r\n"
17510 "Content-Length: 3\r\n\r\n"),
17511 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17512 };
17513
17514 MockRead data_reads[] = {
17515 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17516 MockRead("hello world"),
17517 MockRead(SYNCHRONOUS, OK),
17518 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117519 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417520 session_deps_.socket_factory->AddSocketDataProvider(&data);
17521
17522 TestCompletionCallback callback;
17523
tfarina42834112016-09-22 13:38:2017524 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117525 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417526
17527 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117528 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417529}
17530
bncd16676a2016-07-20 16:23:0117531TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417532 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917533 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217534 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917535 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217536 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417537
17538 HttpRequestInfo request;
17539 request.method = "POST";
17540 request.url = GURL("http://www.foo.com/");
17541 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017542 request.traffic_annotation =
17543 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417544
danakj1fd259a02016-04-16 03:17:0917545 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617546 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417547 // Send headers successfully, but get an error while sending the body.
17548 MockWrite data_writes[] = {
17549 MockWrite("POST / HTTP/1.1\r\n"
17550 "Host: www.foo.com\r\n"
17551 "Connection: keep-alive\r\n"
17552 "Content-Length: 3\r\n\r\n"),
17553 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17554 };
17555
17556 MockRead data_reads[] = {
17557 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17558 MockRead("HTTP/1.0 302 Redirect\r\n"),
17559 MockRead("Location: http://somewhere-else.com/\r\n"),
17560 MockRead("Content-Length: 0\r\n\r\n"),
17561 MockRead(SYNCHRONOUS, OK),
17562 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117563 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417564 session_deps_.socket_factory->AddSocketDataProvider(&data);
17565
17566 TestCompletionCallback callback;
17567
tfarina42834112016-09-22 13:38:2017568 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117569 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417570
17571 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117572 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417573}
17574
bncd16676a2016-07-20 16:23:0117575TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917576 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217577 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917578 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217579 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417580
17581 HttpRequestInfo request;
17582 request.method = "POST";
17583 request.url = GURL("http://www.foo.com/");
17584 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017585 request.traffic_annotation =
17586 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417587
danakj1fd259a02016-04-16 03:17:0917588 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617589 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417590 // Send headers successfully, but get an error while sending the body.
17591 MockWrite data_writes[] = {
17592 MockWrite("POST / HTTP/1.1\r\n"
17593 "Host: www.foo.com\r\n"
17594 "Connection: keep-alive\r\n"
17595 "Content-Length: 3\r\n\r\n"),
17596 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17597 };
17598
17599 MockRead data_reads[] = {
17600 MockRead("HTTP 0.9 rocks!"),
17601 MockRead(SYNCHRONOUS, OK),
17602 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117603 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417604 session_deps_.socket_factory->AddSocketDataProvider(&data);
17605
17606 TestCompletionCallback callback;
17607
tfarina42834112016-09-22 13:38:2017608 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117609 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417610
17611 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117612 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417613}
17614
bncd16676a2016-07-20 16:23:0117615TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917616 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217617 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917618 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217619 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417620
17621 HttpRequestInfo request;
17622 request.method = "POST";
17623 request.url = GURL("http://www.foo.com/");
17624 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017625 request.traffic_annotation =
17626 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417627
danakj1fd259a02016-04-16 03:17:0917628 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617629 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417630 // Send headers successfully, but get an error while sending the body.
17631 MockWrite data_writes[] = {
17632 MockWrite("POST / HTTP/1.1\r\n"
17633 "Host: www.foo.com\r\n"
17634 "Connection: keep-alive\r\n"
17635 "Content-Length: 3\r\n\r\n"),
17636 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17637 };
17638
17639 MockRead data_reads[] = {
17640 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17641 MockRead(SYNCHRONOUS, OK),
17642 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117643 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417644 session_deps_.socket_factory->AddSocketDataProvider(&data);
17645
17646 TestCompletionCallback callback;
17647
tfarina42834112016-09-22 13:38:2017648 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117649 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417650
17651 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117652 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417653}
17654
Bence Békydca6bd92018-01-30 13:43:0617655#if BUILDFLAG(ENABLE_WEBSOCKETS)
17656
17657namespace {
17658
17659void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17660 headers->SetHeader("Connection", "Upgrade");
17661 headers->SetHeader("Upgrade", "websocket");
17662 headers->SetHeader("Origin", "http://www.example.org");
17663 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617664}
17665
17666} // namespace
17667
17668TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Béky2fcf4fa2018-04-06 20:06:0117669 for (bool secure : {true, false}) {
17670 MockWrite data_writes[] = {
17671 MockWrite("GET / HTTP/1.1\r\n"
17672 "Host: www.example.org\r\n"
17673 "Connection: Upgrade\r\n"
17674 "Upgrade: websocket\r\n"
17675 "Origin: http://www.example.org\r\n"
17676 "Sec-WebSocket-Version: 13\r\n"
17677 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17678 "Sec-WebSocket-Extensions: permessage-deflate; "
17679 "client_max_window_bits\r\n\r\n")};
17680
17681 MockRead data_reads[] = {
17682 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17683 "Upgrade: websocket\r\n"
17684 "Connection: Upgrade\r\n"
17685 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
17686
Ryan Sleevib8d7ea02018-05-07 20:01:0117687 StaticSocketDataProvider data(data_reads, data_writes);
Bence Béky2fcf4fa2018-04-06 20:06:0117688 session_deps_.socket_factory->AddSocketDataProvider(&data);
17689 SSLSocketDataProvider ssl(ASYNC, OK);
17690 if (secure)
17691 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
Bence Békydca6bd92018-01-30 13:43:0617692
17693 HttpRequestInfo request;
17694 request.method = "GET";
Bence Béky2fcf4fa2018-04-06 20:06:0117695 request.url =
17696 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17697 AddWebSocketHeaders(&request.extra_headers);
Ramin Halavatib5e433e2018-02-07 07:41:1017698 request.traffic_annotation =
17699 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617700
Bence Béky2fcf4fa2018-04-06 20:06:0117701 TestWebSocketHandshakeStreamCreateHelper
17702 websocket_handshake_stream_create_helper;
Bence Béky8d1c6052018-02-07 12:48:1517703
Bence Béky2fcf4fa2018-04-06 20:06:0117704 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Bence Békydca6bd92018-01-30 13:43:0617705 HttpNetworkTransaction trans(LOW, session.get());
17706 trans.SetWebSocketHandshakeStreamCreateHelper(
Bence Béky2fcf4fa2018-04-06 20:06:0117707 &websocket_handshake_stream_create_helper);
Bence Békydca6bd92018-01-30 13:43:0617708
17709 TestCompletionCallback callback;
Bence Béky2fcf4fa2018-04-06 20:06:0117710 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Bence Békydca6bd92018-01-30 13:43:0617712
Bence Béky2fcf4fa2018-04-06 20:06:0117713 const HttpStreamRequest* stream_request = trans.stream_request_.get();
17714 ASSERT_TRUE(stream_request);
17715 EXPECT_EQ(&websocket_handshake_stream_create_helper,
17716 stream_request->websocket_handshake_stream_create_helper());
17717
17718 rv = callback.WaitForResult();
17719 EXPECT_THAT(rv, IsOk());
17720
17721 EXPECT_TRUE(data.AllReadDataConsumed());
17722 EXPECT_TRUE(data.AllWriteDataConsumed());
Bence Békydca6bd92018-01-30 13:43:0617723 }
17724}
17725
Adam Rice425cf122015-01-19 06:18:2417726// Verify that proxy headers are not sent to the destination server when
17727// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117728TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417729 HttpRequestInfo request;
17730 request.method = "GET";
bncce36dca22015-04-21 22:11:2317731 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017732 request.traffic_annotation =
17733 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417734 AddWebSocketHeaders(&request.extra_headers);
17735
17736 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917737 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917738 ProxyResolutionService::CreateFixedFromPacResult(
17739 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417740
danakj1fd259a02016-04-16 03:17:0917741 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417742
17743 // Since a proxy is configured, try to establish a tunnel.
17744 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717745 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17746 "Host: www.example.org:443\r\n"
17747 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417748
17749 // After calling trans->RestartWithAuth(), this is the request we should
17750 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717751 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17752 "Host: www.example.org:443\r\n"
17753 "Proxy-Connection: keep-alive\r\n"
17754 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417755
rsleevidb16bb02015-11-12 23:47:1717756 MockWrite("GET / HTTP/1.1\r\n"
17757 "Host: www.example.org\r\n"
17758 "Connection: Upgrade\r\n"
17759 "Upgrade: websocket\r\n"
17760 "Origin: http://www.example.org\r\n"
17761 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517762 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17763 "Sec-WebSocket-Extensions: permessage-deflate; "
17764 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417765
17766 // The proxy responds to the connect with a 407, using a persistent
17767 // connection.
17768 MockRead data_reads[] = {
17769 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517770 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17771 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17772 "Content-Length: 0\r\n"
17773 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417774
17775 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17776
Bence Béky8d1c6052018-02-07 12:48:1517777 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17778 "Upgrade: websocket\r\n"
17779 "Connection: Upgrade\r\n"
17780 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417781
Ryan Sleevib8d7ea02018-05-07 20:01:0117782 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417783 session_deps_.socket_factory->AddSocketDataProvider(&data);
17784 SSLSocketDataProvider ssl(ASYNC, OK);
17785 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17786
Bence Béky8d1c6052018-02-07 12:48:1517787 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17788
bnc87dcefc2017-05-25 12:47:5817789 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917790 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417791 trans->SetWebSocketHandshakeStreamCreateHelper(
17792 &websocket_stream_create_helper);
17793
17794 {
17795 TestCompletionCallback callback;
17796
tfarina42834112016-09-22 13:38:2017797 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417799
17800 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117801 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417802 }
17803
17804 const HttpResponseInfo* response = trans->GetResponseInfo();
17805 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217806 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417807 EXPECT_EQ(407, response->headers->response_code());
17808
17809 {
17810 TestCompletionCallback callback;
17811
17812 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17813 callback.callback());
robpercival214763f2016-07-01 23:27:0117814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417815
17816 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117817 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417818 }
17819
17820 response = trans->GetResponseInfo();
17821 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217822 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417823
17824 EXPECT_EQ(101, response->headers->response_code());
17825
17826 trans.reset();
17827 session->CloseAllConnections();
17828}
17829
17830// Verify that proxy headers are not sent to the destination server when
17831// establishing a tunnel for an insecure WebSocket connection.
17832// This requires the authentication info to be injected into the auth cache
17833// due to crbug.com/395064
17834// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117835TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417836 HttpRequestInfo request;
17837 request.method = "GET";
bncce36dca22015-04-21 22:11:2317838 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017839 request.traffic_annotation =
17840 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417841 AddWebSocketHeaders(&request.extra_headers);
17842
17843 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917844 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917845 ProxyResolutionService::CreateFixedFromPacResult(
17846 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417847
danakj1fd259a02016-04-16 03:17:0917848 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417849
17850 MockWrite data_writes[] = {
17851 // Try to establish a tunnel for the WebSocket connection, with
17852 // credentials. Because WebSockets have a separate set of socket pools,
17853 // they cannot and will not use the same TCP/IP connection as the
17854 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517855 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17856 "Host: www.example.org:80\r\n"
17857 "Proxy-Connection: keep-alive\r\n"
17858 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417859
Bence Béky8d1c6052018-02-07 12:48:1517860 MockWrite("GET / HTTP/1.1\r\n"
17861 "Host: www.example.org\r\n"
17862 "Connection: Upgrade\r\n"
17863 "Upgrade: websocket\r\n"
17864 "Origin: http://www.example.org\r\n"
17865 "Sec-WebSocket-Version: 13\r\n"
17866 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17867 "Sec-WebSocket-Extensions: permessage-deflate; "
17868 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417869
17870 MockRead data_reads[] = {
17871 // HTTP CONNECT with credentials.
17872 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17873
17874 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517875 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17876 "Upgrade: websocket\r\n"
17877 "Connection: Upgrade\r\n"
17878 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417879
Ryan Sleevib8d7ea02018-05-07 20:01:0117880 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417881 session_deps_.socket_factory->AddSocketDataProvider(&data);
17882
17883 session->http_auth_cache()->Add(
17884 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17885 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17886
Bence Béky8d1c6052018-02-07 12:48:1517887 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17888
bnc87dcefc2017-05-25 12:47:5817889 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917890 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417891 trans->SetWebSocketHandshakeStreamCreateHelper(
17892 &websocket_stream_create_helper);
17893
17894 TestCompletionCallback callback;
17895
tfarina42834112016-09-22 13:38:2017896 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417898
17899 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117900 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417901
17902 const HttpResponseInfo* response = trans->GetResponseInfo();
17903 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217904 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417905
17906 EXPECT_EQ(101, response->headers->response_code());
17907
17908 trans.reset();
17909 session->CloseAllConnections();
17910}
17911
Matt Menke1d6093e32019-03-22 17:33:4317912// WebSockets over QUIC is not supported, including over QUIC proxies.
17913TEST_F(HttpNetworkTransactionTest, WebSocketNotSentOverQuicProxy) {
17914 for (bool secure : {true, false}) {
17915 SCOPED_TRACE(secure);
17916 session_deps_.proxy_resolution_service =
17917 ProxyResolutionService::CreateFixedFromPacResult(
17918 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
17919 session_deps_.enable_quic = true;
17920
17921 HttpRequestInfo request;
17922 request.url =
17923 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17924 AddWebSocketHeaders(&request.extra_headers);
17925 request.traffic_annotation =
17926 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17927
17928 TestWebSocketHandshakeStreamCreateHelper
17929 websocket_handshake_stream_create_helper;
17930
17931 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17932 HttpNetworkTransaction trans(LOW, session.get());
17933 trans.SetWebSocketHandshakeStreamCreateHelper(
17934 &websocket_handshake_stream_create_helper);
17935
17936 TestCompletionCallback callback;
17937 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17938 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17939
17940 rv = callback.WaitForResult();
17941 EXPECT_THAT(rv, IsError(ERR_NO_SUPPORTED_PROXIES));
17942 }
17943}
17944
Bence Békydca6bd92018-01-30 13:43:0617945#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17946
bncd16676a2016-07-20 16:23:0117947TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917948 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217949 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917950 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217951 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217952
17953 HttpRequestInfo request;
17954 request.method = "POST";
17955 request.url = GURL("http://www.foo.com/");
17956 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017957 request.traffic_annotation =
17958 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217959
danakj1fd259a02016-04-16 03:17:0917960 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617961 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217962 MockWrite data_writes[] = {
17963 MockWrite("POST / HTTP/1.1\r\n"
17964 "Host: www.foo.com\r\n"
17965 "Connection: keep-alive\r\n"
17966 "Content-Length: 3\r\n\r\n"),
17967 MockWrite("foo"),
17968 };
17969
17970 MockRead data_reads[] = {
17971 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17972 MockRead(SYNCHRONOUS, OK),
17973 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117974 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217975 session_deps_.socket_factory->AddSocketDataProvider(&data);
17976
17977 TestCompletionCallback callback;
17978
17979 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017980 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117981 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217982
17983 std::string response_data;
bnc691fda62016-08-12 00:43:1617984 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217985
Ryan Sleevib8d7ea02018-05-07 20:01:0117986 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17987 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217988}
17989
bncd16676a2016-07-20 16:23:0117990TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917991 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217992 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917993 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217994 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217995
17996 HttpRequestInfo request;
17997 request.method = "POST";
17998 request.url = GURL("http://www.foo.com/");
17999 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1018000 request.traffic_annotation =
18001 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218002
danakj1fd259a02016-04-16 03:17:0918003 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618004 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218005 MockWrite data_writes[] = {
18006 MockWrite("POST / HTTP/1.1\r\n"
18007 "Host: www.foo.com\r\n"
18008 "Connection: keep-alive\r\n"
18009 "Content-Length: 3\r\n\r\n"),
18010 MockWrite("foo"),
18011 };
18012
18013 MockRead data_reads[] = {
18014 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
18015 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18016 MockRead(SYNCHRONOUS, OK),
18017 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118018 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218019 session_deps_.socket_factory->AddSocketDataProvider(&data);
18020
18021 TestCompletionCallback callback;
18022
18023 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018024 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0118025 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218026
18027 std::string response_data;
bnc691fda62016-08-12 00:43:1618028 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218029
Ryan Sleevib8d7ea02018-05-07 20:01:0118030 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18031 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218032}
18033
bncd16676a2016-07-20 16:23:0118034TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2218035 ChunkedUploadDataStream upload_data_stream(0);
18036
18037 HttpRequestInfo request;
18038 request.method = "POST";
18039 request.url = GURL("http://www.foo.com/");
18040 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1018041 request.traffic_annotation =
18042 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218043
danakj1fd259a02016-04-16 03:17:0918044 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618045 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218046 // Send headers successfully, but get an error while sending the body.
18047 MockWrite data_writes[] = {
18048 MockWrite("POST / HTTP/1.1\r\n"
18049 "Host: www.foo.com\r\n"
18050 "Connection: keep-alive\r\n"
18051 "Transfer-Encoding: chunked\r\n\r\n"),
18052 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
18053 };
18054
18055 MockRead data_reads[] = {
18056 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18057 MockRead(SYNCHRONOUS, OK),
18058 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118059 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218060 session_deps_.socket_factory->AddSocketDataProvider(&data);
18061
18062 TestCompletionCallback callback;
18063
18064 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018065 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2218066
18067 base::RunLoop().RunUntilIdle();
18068 upload_data_stream.AppendData("f", 1, false);
18069
18070 base::RunLoop().RunUntilIdle();
18071 upload_data_stream.AppendData("oo", 2, true);
18072
robpercival214763f2016-07-01 23:27:0118073 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218074
18075 std::string response_data;
bnc691fda62016-08-12 00:43:1618076 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218077
Ryan Sleevib8d7ea02018-05-07 20:01:0118078 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18079 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218080}
18081
eustasc7d27da2017-04-06 10:33:2018082void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
18083 const std::string& accept_encoding,
18084 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0318085 const std::string& location,
eustasc7d27da2017-04-06 10:33:2018086 bool should_match) {
18087 HttpRequestInfo request;
18088 request.method = "GET";
18089 request.url = GURL("http://www.foo.com/");
18090 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
18091 accept_encoding);
Ramin Halavatib5e433e2018-02-07 07:41:1018092 request.traffic_annotation =
18093 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2018094
18095 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
18096 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18097 // Send headers successfully, but get an error while sending the body.
18098 MockWrite data_writes[] = {
18099 MockWrite("GET / HTTP/1.1\r\n"
18100 "Host: www.foo.com\r\n"
18101 "Connection: keep-alive\r\n"
18102 "Accept-Encoding: "),
18103 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
18104 };
18105
sky50576f32017-05-01 19:28:0318106 std::string response_code = "200 OK";
18107 std::string extra;
18108 if (!location.empty()) {
18109 response_code = "301 Redirect\r\nLocation: ";
18110 response_code.append(location);
18111 }
18112
eustasc7d27da2017-04-06 10:33:2018113 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0318114 MockRead("HTTP/1.0 "),
18115 MockRead(response_code.data()),
18116 MockRead("\r\nContent-Encoding: "),
18117 MockRead(content_encoding.data()),
18118 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2018119 MockRead(SYNCHRONOUS, OK),
18120 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118121 StaticSocketDataProvider data(data_reads, data_writes);
eustasc7d27da2017-04-06 10:33:2018122 session_deps->socket_factory->AddSocketDataProvider(&data);
18123
18124 TestCompletionCallback callback;
18125
18126 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18127 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18128
18129 rv = callback.WaitForResult();
18130 if (should_match) {
18131 EXPECT_THAT(rv, IsOk());
18132 } else {
18133 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
18134 }
18135}
18136
18137TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0318138 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2018139}
18140
18141TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0318142 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
18143 true);
eustasc7d27da2017-04-06 10:33:2018144}
18145
18146TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
18147 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0318148 "", false);
18149}
18150
18151TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
18152 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
18153 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2018154}
18155
xunjieli96f2a402017-06-05 17:24:2718156TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
18157 ProxyConfig proxy_config;
18158 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18159 proxy_config.set_pac_mandatory(true);
18160 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918161 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918162 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18163 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0418164 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2718165
18166 HttpRequestInfo request;
18167 request.method = "GET";
18168 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018169 request.traffic_annotation =
18170 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718171
18172 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18173 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18174
18175 TestCompletionCallback callback;
18176
18177 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18178 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18179 EXPECT_THAT(callback.WaitForResult(),
18180 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18181}
18182
18183TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
18184 ProxyConfig proxy_config;
18185 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18186 proxy_config.set_pac_mandatory(true);
18187 MockAsyncProxyResolverFactory* proxy_resolver_factory =
18188 new MockAsyncProxyResolverFactory(false);
18189 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918190 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918191 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18192 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5918193 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2718194 HttpRequestInfo request;
18195 request.method = "GET";
18196 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018197 request.traffic_annotation =
18198 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718199
18200 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18201 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18202
18203 TestCompletionCallback callback;
18204 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18205 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18206
18207 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
18208 ERR_FAILED, &resolver);
18209 EXPECT_THAT(callback.WaitForResult(),
18210 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18211}
18212
18213TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5918214 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4918215 ProxyResolutionService::CreateFixedFromPacResult(
18216 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718217 session_deps_.enable_quic = false;
18218 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18219
18220 HttpRequestInfo request;
18221 request.method = "GET";
18222 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018223 request.traffic_annotation =
18224 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718225
18226 TestCompletionCallback callback;
18227 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18228 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18229 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18230
18231 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18232}
18233
Douglas Creager3cb042052018-11-06 23:08:5218234//-----------------------------------------------------------------------------
Douglas Creager134b52e2018-11-09 18:00:1418235// Reporting tests
18236
18237#if BUILDFLAG(ENABLE_REPORTING)
18238class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest {
18239 protected:
18240 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618241 HttpNetworkTransactionTest::SetUp();
Douglas Creager134b52e2018-11-09 18:00:1418242 auto test_reporting_context = std::make_unique<TestReportingContext>(
18243 &clock_, &tick_clock_, ReportingPolicy());
18244 test_reporting_context_ = test_reporting_context.get();
18245 session_deps_.reporting_service =
18246 ReportingService::CreateForTesting(std::move(test_reporting_context));
18247 }
18248
18249 TestReportingContext* reporting_context() const {
18250 return test_reporting_context_;
18251 }
18252
18253 void clear_reporting_service() {
18254 session_deps_.reporting_service.reset();
18255 test_reporting_context_ = nullptr;
18256 }
18257
18258 // Makes an HTTPS request that should install a valid Reporting policy.
Lily Chenfec60d92019-01-24 01:16:4218259 void RequestPolicy(CertStatus cert_status = 0) {
18260 HttpRequestInfo request;
18261 request.method = "GET";
18262 request.url = GURL(url_);
18263 request.traffic_annotation =
18264 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18265
Lily Chend3930e72019-03-01 19:31:1118266 MockWrite data_writes[] = {
18267 MockWrite("GET / HTTP/1.1\r\n"
18268 "Host: www.example.org\r\n"
18269 "Connection: keep-alive\r\n\r\n"),
18270 };
Douglas Creager134b52e2018-11-09 18:00:1418271 MockRead data_reads[] = {
18272 MockRead("HTTP/1.0 200 OK\r\n"),
18273 MockRead("Report-To: {\"group\": \"nel\", \"max_age\": 86400, "
18274 "\"endpoints\": [{\"url\": "
18275 "\"https://www.example.org/upload/\"}]}\r\n"),
18276 MockRead("\r\n"),
18277 MockRead("hello world"),
18278 MockRead(SYNCHRONOUS, OK),
18279 };
Douglas Creager134b52e2018-11-09 18:00:1418280
Lily Chenfec60d92019-01-24 01:16:4218281 StaticSocketDataProvider reads(data_reads, data_writes);
18282 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager134b52e2018-11-09 18:00:1418283
18284 SSLSocketDataProvider ssl(ASYNC, OK);
18285 if (request.url.SchemeIsCryptographic()) {
18286 ssl.ssl_info.cert =
18287 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18288 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218289 ssl.ssl_info.cert_status = cert_status;
Douglas Creager134b52e2018-11-09 18:00:1418290 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18291 }
18292
Douglas Creager134b52e2018-11-09 18:00:1418293 TestCompletionCallback callback;
18294 auto session = CreateSession(&session_deps_);
18295 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18296 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
Lily Chenfec60d92019-01-24 01:16:4218297 EXPECT_THAT(callback.GetResult(rv), IsOk());
Douglas Creager134b52e2018-11-09 18:00:1418298 }
18299
18300 protected:
18301 std::string url_ = "https://www.example.org/";
Douglas Creager134b52e2018-11-09 18:00:1418302
18303 private:
18304 TestReportingContext* test_reporting_context_;
18305};
18306
18307TEST_F(HttpNetworkTransactionReportingTest,
18308 DontProcessReportToHeaderNoService) {
18309 base::HistogramTester histograms;
18310 clear_reporting_service();
18311 RequestPolicy();
18312 histograms.ExpectBucketCount(
18313 ReportingHeaderParser::kHeaderOutcomeHistogram,
18314 ReportingHeaderParser::HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE, 1);
18315}
18316
18317TEST_F(HttpNetworkTransactionReportingTest, DontProcessReportToHeaderHttp) {
18318 base::HistogramTester histograms;
18319 url_ = "http://www.example.org/";
18320 RequestPolicy();
18321 histograms.ExpectBucketCount(
18322 ReportingHeaderParser::kHeaderOutcomeHistogram,
18323 ReportingHeaderParser::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18324}
18325
18326TEST_F(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
18327 RequestPolicy();
Lily Chenefb6fcf2019-04-19 04:17:5418328 ASSERT_EQ(1u, reporting_context()->cache()->GetEndpointCount());
18329 const ReportingClient endpoint =
18330 reporting_context()->cache()->GetEndpointForTesting(
18331 url::Origin::Create(GURL("https://www.example.org/")), "nel",
18332 GURL("https://www.example.org/upload/"));
18333 EXPECT_TRUE(endpoint);
Douglas Creager134b52e2018-11-09 18:00:1418334}
18335
18336TEST_F(HttpNetworkTransactionReportingTest,
18337 DontProcessReportToHeaderInvalidHttps) {
18338 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218339 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18340 RequestPolicy(cert_status);
Douglas Creager134b52e2018-11-09 18:00:1418341 histograms.ExpectBucketCount(
18342 ReportingHeaderParser::kHeaderOutcomeHistogram,
18343 ReportingHeaderParser::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR, 1);
18344}
18345#endif // BUILDFLAG(ENABLE_REPORTING)
18346
18347//-----------------------------------------------------------------------------
Douglas Creager3cb042052018-11-06 23:08:5218348// Network Error Logging tests
18349
18350#if BUILDFLAG(ENABLE_REPORTING)
Lily Chenfec60d92019-01-24 01:16:4218351namespace {
18352
18353const char kUserAgent[] = "Mozilla/1.0";
18354const char kReferrer[] = "https://www.referrer.org/";
18355
18356} // namespace
18357
Douglas Creager3cb042052018-11-06 23:08:5218358class HttpNetworkTransactionNetworkErrorLoggingTest
18359 : public HttpNetworkTransactionTest {
18360 protected:
18361 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618362 HttpNetworkTransactionTest::SetUp();
Douglas Creager3cb042052018-11-06 23:08:5218363 auto network_error_logging_service =
18364 std::make_unique<TestNetworkErrorLoggingService>();
18365 test_network_error_logging_service_ = network_error_logging_service.get();
18366 session_deps_.network_error_logging_service =
18367 std::move(network_error_logging_service);
Lily Chenfec60d92019-01-24 01:16:4218368
18369 extra_headers_.SetHeader("User-Agent", kUserAgent);
18370 extra_headers_.SetHeader("Referer", kReferrer);
18371
18372 request_.method = "GET";
18373 request_.url = GURL(url_);
18374 request_.extra_headers = extra_headers_;
18375 request_.reporting_upload_depth = reporting_upload_depth_;
18376 request_.traffic_annotation =
18377 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Douglas Creager3cb042052018-11-06 23:08:5218378 }
18379
18380 TestNetworkErrorLoggingService* network_error_logging_service() const {
18381 return test_network_error_logging_service_;
18382 }
18383
18384 void clear_network_error_logging_service() {
18385 session_deps_.network_error_logging_service.reset();
18386 test_network_error_logging_service_ = nullptr;
18387 }
18388
18389 // Makes an HTTPS request that should install a valid NEL policy.
Lily Chenfec60d92019-01-24 01:16:4218390 void RequestPolicy(CertStatus cert_status = 0) {
Douglas Creageref5eecdc2018-11-09 20:50:3618391 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318392 MockWrite data_writes[] = {
18393 MockWrite("GET / HTTP/1.1\r\n"
18394 "Host: www.example.org\r\n"
18395 "Connection: keep-alive\r\n"),
18396 MockWrite(ASYNC, extra_header_string.data(),
18397 extra_header_string.size()),
18398 };
Lily Chend3930e72019-03-01 19:31:1118399 MockRead data_reads[] = {
18400 MockRead("HTTP/1.0 200 OK\r\n"),
18401 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18402 MockRead("\r\n"),
18403 MockRead("hello world"),
18404 MockRead(SYNCHRONOUS, OK),
18405 };
Douglas Creager3cb042052018-11-06 23:08:5218406
Lily Chenfec60d92019-01-24 01:16:4218407 StaticSocketDataProvider reads(data_reads, data_writes);
18408 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager3cb042052018-11-06 23:08:5218409
18410 SSLSocketDataProvider ssl(ASYNC, OK);
Lily Chenfec60d92019-01-24 01:16:4218411 if (request_.url.SchemeIsCryptographic()) {
Douglas Creager3cb042052018-11-06 23:08:5218412 ssl.ssl_info.cert =
18413 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18414 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218415 ssl.ssl_info.cert_status = cert_status;
Douglas Creager3cb042052018-11-06 23:08:5218416 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18417 }
18418
Douglas Creager3cb042052018-11-06 23:08:5218419 TestCompletionCallback callback;
18420 auto session = CreateSession(&session_deps_);
18421 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
Lily Chenfec60d92019-01-24 01:16:4218422 int rv = trans.Start(&request_, callback.callback(), NetLogWithSource());
18423 EXPECT_THAT(callback.GetResult(rv), IsOk());
18424
18425 std::string response_data;
18426 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
18427 EXPECT_EQ("hello world", response_data);
18428 }
18429
18430 void CheckReport(size_t index,
18431 int status_code,
18432 int error_type,
18433 IPAddress server_ip = IPAddress::IPv4Localhost()) {
18434 ASSERT_LT(index, network_error_logging_service()->errors().size());
18435
18436 const NetworkErrorLoggingService::RequestDetails& error =
18437 network_error_logging_service()->errors()[index];
18438 EXPECT_EQ(url_, error.uri);
18439 EXPECT_EQ(kReferrer, error.referrer);
18440 EXPECT_EQ(kUserAgent, error.user_agent);
18441 EXPECT_EQ(server_ip, error.server_ip);
18442 EXPECT_EQ("http/1.1", error.protocol);
18443 EXPECT_EQ("GET", error.method);
18444 EXPECT_EQ(status_code, error.status_code);
18445 EXPECT_EQ(error_type, error.type);
18446 EXPECT_EQ(0, error.reporting_upload_depth);
Douglas Creager3cb042052018-11-06 23:08:5218447 }
18448
18449 protected:
18450 std::string url_ = "https://www.example.org/";
18451 CertStatus cert_status_ = 0;
Lily Chenfec60d92019-01-24 01:16:4218452 HttpRequestInfo request_;
Douglas Creageref5eecdc2018-11-09 20:50:3618453 HttpRequestHeaders extra_headers_;
18454 int reporting_upload_depth_ = 0;
Douglas Creager3cb042052018-11-06 23:08:5218455
18456 private:
18457 TestNetworkErrorLoggingService* test_network_error_logging_service_;
18458};
18459
18460TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18461 DontProcessNelHeaderNoService) {
18462 base::HistogramTester histograms;
18463 clear_network_error_logging_service();
18464 RequestPolicy();
18465 histograms.ExpectBucketCount(
18466 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18467 NetworkErrorLoggingService::HeaderOutcome::
18468 DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE,
18469 1);
18470}
18471
18472TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18473 DontProcessNelHeaderHttp) {
18474 base::HistogramTester histograms;
18475 url_ = "http://www.example.org/";
Lily Chenfec60d92019-01-24 01:16:4218476 request_.url = GURL(url_);
Douglas Creager3cb042052018-11-06 23:08:5218477 RequestPolicy();
18478 histograms.ExpectBucketCount(
18479 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18480 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18481}
18482
Lily Chen90ae93cc2019-02-14 01:15:3918483// Don't set NEL policies received on a proxied connection.
18484TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18485 DontProcessNelHeaderProxy) {
18486 session_deps_.proxy_resolution_service =
18487 ProxyResolutionService::CreateFixedFromPacResult(
18488 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
18489 BoundTestNetLog log;
18490 session_deps_.net_log = log.bound().net_log();
18491 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18492
18493 HttpRequestInfo request;
18494 request.method = "GET";
18495 request.url = GURL("https://www.example.org/");
18496 request.traffic_annotation =
18497 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18498
18499 // Since we have proxy, should try to establish tunnel.
18500 MockWrite data_writes1[] = {
18501 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
18502 "Host: www.example.org:443\r\n"
18503 "Proxy-Connection: keep-alive\r\n\r\n"),
18504
18505 MockWrite("GET / HTTP/1.1\r\n"
18506 "Host: www.example.org\r\n"
18507 "Connection: keep-alive\r\n\r\n"),
18508 };
18509
18510 MockRead data_reads1[] = {
18511 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
18512
18513 MockRead("HTTP/1.1 200 OK\r\n"),
18514 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18515 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18516 MockRead("Content-Length: 100\r\n\r\n"),
18517 MockRead(SYNCHRONOUS, OK),
18518 };
18519
18520 StaticSocketDataProvider data1(data_reads1, data_writes1);
18521 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18522 SSLSocketDataProvider ssl(ASYNC, OK);
18523 ssl.ssl_info.cert =
18524 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18525 ASSERT_TRUE(ssl.ssl_info.cert);
18526 ssl.ssl_info.cert_status = 0;
18527 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18528
18529 TestCompletionCallback callback1;
18530 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18531
18532 int rv = trans.Start(&request, callback1.callback(), log.bound());
18533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18534
18535 rv = callback1.WaitForResult();
18536 EXPECT_THAT(rv, IsOk());
18537
18538 const HttpResponseInfo* response = trans.GetResponseInfo();
18539 ASSERT_TRUE(response);
18540 EXPECT_EQ(200, response->headers->response_code());
18541 EXPECT_TRUE(response->was_fetched_via_proxy);
18542
18543 // No NEL header was set.
18544 EXPECT_EQ(0u, network_error_logging_service()->headers().size());
18545}
18546
Douglas Creager3cb042052018-11-06 23:08:5218547TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) {
18548 RequestPolicy();
18549 ASSERT_EQ(1u, network_error_logging_service()->headers().size());
18550 const auto& header = network_error_logging_service()->headers()[0];
18551 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18552 header.origin);
18553 EXPECT_EQ(IPAddress::IPv4Localhost(), header.received_ip_address);
18554 EXPECT_EQ("{\"report_to\": \"nel\", \"max_age\": 86400}", header.value);
18555}
18556
18557TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18558 DontProcessNelHeaderInvalidHttps) {
18559 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218560 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18561 RequestPolicy(cert_status);
Douglas Creager3cb042052018-11-06 23:08:5218562 histograms.ExpectBucketCount(
18563 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18564 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR,
18565 1);
18566}
Douglas Creageref5eecdc2018-11-09 20:50:3618567
Lily Chenfec60d92019-01-24 01:16:4218568TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportSuccess) {
Douglas Creageref5eecdc2018-11-09 20:50:3618569 RequestPolicy();
18570 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4218571 CheckReport(0 /* index */, 200 /* status_code */, OK);
18572}
18573
18574TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18575 CreateReportErrorAfterStart) {
18576 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18577 auto trans =
18578 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18579
18580 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
18581 StaticSocketDataProvider data;
18582 data.set_connect_data(mock_connect);
18583 session_deps_.socket_factory->AddSocketDataProvider(&data);
18584
18585 TestCompletionCallback callback;
18586
18587 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18588 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18589
18590 trans.reset();
18591
18592 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18593 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18594 IPAddress() /* server_ip */);
18595}
18596
18597// Same as above except the error is ASYNC
18598TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18599 CreateReportErrorAfterStartAsync) {
18600 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18601 auto trans =
18602 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18603
18604 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
18605 StaticSocketDataProvider data;
18606 data.set_connect_data(mock_connect);
18607 session_deps_.socket_factory->AddSocketDataProvider(&data);
18608
18609 TestCompletionCallback callback;
18610
18611 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18612 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18613
18614 trans.reset();
18615
18616 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18617 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18618 IPAddress() /* server_ip */);
18619}
18620
18621TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18622 CreateReportReadBodyError) {
18623 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318624 MockWrite data_writes[] = {
18625 MockWrite("GET / HTTP/1.1\r\n"
18626 "Host: www.example.org\r\n"
18627 "Connection: keep-alive\r\n"),
18628 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18629 };
Lily Chend3930e72019-03-01 19:31:1118630 MockRead data_reads[] = {
18631 MockRead("HTTP/1.0 200 OK\r\n"),
18632 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18633 MockRead("hello world"),
18634 MockRead(SYNCHRONOUS, OK),
18635 };
Lily Chenfec60d92019-01-24 01:16:4218636
18637 StaticSocketDataProvider reads(data_reads, data_writes);
18638 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18639
18640 SSLSocketDataProvider ssl(ASYNC, OK);
18641 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18642
18643 // Log start time
18644 base::TimeTicks start_time = base::TimeTicks::Now();
18645
18646 TestCompletionCallback callback;
18647 auto session = CreateSession(&session_deps_);
18648 auto trans =
18649 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18650 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18651 EXPECT_THAT(callback.GetResult(rv), IsOk());
18652
18653 const HttpResponseInfo* response = trans->GetResponseInfo();
18654 ASSERT_TRUE(response);
18655
18656 EXPECT_TRUE(response->headers);
18657 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18658
18659 std::string response_data;
18660 rv = ReadTransaction(trans.get(), &response_data);
18661 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18662
18663 trans.reset();
18664
18665 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18666
18667 CheckReport(0 /* index */, 200 /* status_code */,
18668 ERR_CONTENT_LENGTH_MISMATCH);
18669 const NetworkErrorLoggingService::RequestDetails& error =
18670 network_error_logging_service()->errors()[0];
18671 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18672}
18673
18674// Same as above except the final read is ASYNC.
18675TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18676 CreateReportReadBodyErrorAsync) {
18677 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318678 MockWrite data_writes[] = {
18679 MockWrite("GET / HTTP/1.1\r\n"
18680 "Host: www.example.org\r\n"
18681 "Connection: keep-alive\r\n"),
18682 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18683 };
Lily Chend3930e72019-03-01 19:31:1118684 MockRead data_reads[] = {
18685 MockRead("HTTP/1.0 200 OK\r\n"),
18686 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18687 MockRead("hello world"),
18688 MockRead(ASYNC, OK),
18689 };
Lily Chenfec60d92019-01-24 01:16:4218690
18691 StaticSocketDataProvider reads(data_reads, data_writes);
18692 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18693
18694 SSLSocketDataProvider ssl(ASYNC, OK);
18695 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18696
18697 // Log start time
18698 base::TimeTicks start_time = base::TimeTicks::Now();
18699
18700 TestCompletionCallback callback;
18701 auto session = CreateSession(&session_deps_);
18702 auto trans =
18703 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18704 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18705 EXPECT_THAT(callback.GetResult(rv), IsOk());
18706
18707 const HttpResponseInfo* response = trans->GetResponseInfo();
18708 ASSERT_TRUE(response);
18709
18710 EXPECT_TRUE(response->headers);
18711 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18712
18713 std::string response_data;
18714 rv = ReadTransaction(trans.get(), &response_data);
18715 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18716
18717 trans.reset();
18718
18719 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18720
18721 CheckReport(0 /* index */, 200 /* status_code */,
18722 ERR_CONTENT_LENGTH_MISMATCH);
18723 const NetworkErrorLoggingService::RequestDetails& error =
18724 network_error_logging_service()->errors()[0];
18725 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18726}
18727
18728TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18729 CreateReportRestartWithAuth) {
18730 std::string extra_header_string = extra_headers_.ToString();
18731 static const base::TimeDelta kSleepDuration =
18732 base::TimeDelta::FromMilliseconds(10);
18733
18734 MockWrite data_writes1[] = {
18735 MockWrite("GET / HTTP/1.1\r\n"
18736 "Host: www.example.org\r\n"
18737 "Connection: keep-alive\r\n"),
18738 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18739 };
18740
18741 MockRead data_reads1[] = {
18742 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18743 // Give a couple authenticate options (only the middle one is actually
18744 // supported).
18745 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18746 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18747 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18748 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18749 // Large content-length -- won't matter, as connection will be reset.
18750 MockRead("Content-Length: 10000\r\n\r\n"),
18751 MockRead(SYNCHRONOUS, ERR_FAILED),
18752 };
18753
18754 // After calling trans->RestartWithAuth(), this is the request we should
18755 // be issuing -- the final header line contains the credentials.
18756 MockWrite data_writes2[] = {
18757 MockWrite("GET / HTTP/1.1\r\n"
18758 "Host: www.example.org\r\n"
18759 "Connection: keep-alive\r\n"
18760 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18761 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18762 };
18763
18764 // Lastly, the server responds with the actual content.
18765 MockRead data_reads2[] = {
18766 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18767 MockRead("hello world"),
18768 MockRead(SYNCHRONOUS, OK),
18769 };
18770
18771 StaticSocketDataProvider data1(data_reads1, data_writes1);
18772 StaticSocketDataProvider data2(data_reads2, data_writes2);
18773 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18774 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18775
18776 SSLSocketDataProvider ssl1(ASYNC, OK);
18777 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18778 SSLSocketDataProvider ssl2(ASYNC, OK);
18779 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18780
18781 base::TimeTicks start_time = base::TimeTicks::Now();
18782 base::TimeTicks restart_time;
18783
18784 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18785 auto trans =
18786 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18787
18788 TestCompletionCallback callback1;
18789
18790 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18791 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18792
18793 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18794
18795 TestCompletionCallback callback2;
18796
18797 // Wait 10 ms then restart with auth
18798 FastForwardBy(kSleepDuration);
18799 restart_time = base::TimeTicks::Now();
18800 rv =
18801 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18802 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18803
18804 std::string response_data;
18805 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18806 EXPECT_EQ("hello world", response_data);
18807
18808 trans.reset();
18809
18810 // One 401 report for the auth challenge, then a 200 report for the successful
18811 // retry. Note that we don't report the error draining the body, as the first
18812 // request already generated a report for the auth challenge.
18813 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18814
18815 // Check error report contents
18816 CheckReport(0 /* index */, 401 /* status_code */, OK);
18817 CheckReport(1 /* index */, 200 /* status_code */, OK);
18818
18819 const NetworkErrorLoggingService::RequestDetails& error1 =
18820 network_error_logging_service()->errors()[0];
18821 const NetworkErrorLoggingService::RequestDetails& error2 =
18822 network_error_logging_service()->errors()[1];
18823
18824 // Sanity-check elapsed time values
18825 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18826 // Check that the start time is refreshed when restarting with auth.
18827 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18828}
18829
18830// Same as above, except draining the body before restarting fails
18831// asynchronously.
18832TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18833 CreateReportRestartWithAuthAsync) {
18834 std::string extra_header_string = extra_headers_.ToString();
18835 static const base::TimeDelta kSleepDuration =
18836 base::TimeDelta::FromMilliseconds(10);
18837
18838 MockWrite data_writes1[] = {
18839 MockWrite("GET / HTTP/1.1\r\n"
18840 "Host: www.example.org\r\n"
18841 "Connection: keep-alive\r\n"),
18842 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18843 };
18844
18845 MockRead data_reads1[] = {
18846 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18847 // Give a couple authenticate options (only the middle one is actually
18848 // supported).
18849 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18850 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18851 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18852 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18853 // Large content-length -- won't matter, as connection will be reset.
18854 MockRead("Content-Length: 10000\r\n\r\n"),
18855 MockRead(ASYNC, ERR_FAILED),
18856 };
18857
18858 // After calling trans->RestartWithAuth(), this is the request we should
18859 // be issuing -- the final header line contains the credentials.
18860 MockWrite data_writes2[] = {
18861 MockWrite("GET / HTTP/1.1\r\n"
18862 "Host: www.example.org\r\n"
18863 "Connection: keep-alive\r\n"
18864 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18865 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18866 };
18867
18868 // Lastly, the server responds with the actual content.
18869 MockRead data_reads2[] = {
18870 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18871 MockRead("hello world"),
18872 MockRead(SYNCHRONOUS, OK),
18873 };
18874
18875 StaticSocketDataProvider data1(data_reads1, data_writes1);
18876 StaticSocketDataProvider data2(data_reads2, data_writes2);
18877 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18878 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18879
18880 SSLSocketDataProvider ssl1(ASYNC, OK);
18881 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18882 SSLSocketDataProvider ssl2(ASYNC, OK);
18883 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18884
18885 base::TimeTicks start_time = base::TimeTicks::Now();
18886 base::TimeTicks restart_time;
18887
18888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18889 auto trans =
18890 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18891
18892 TestCompletionCallback callback1;
18893
18894 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18895 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18896
18897 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18898
18899 TestCompletionCallback callback2;
18900
18901 // Wait 10 ms then restart with auth
18902 FastForwardBy(kSleepDuration);
18903 restart_time = base::TimeTicks::Now();
18904 rv =
18905 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18906 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18907
18908 std::string response_data;
18909 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18910 EXPECT_EQ("hello world", response_data);
18911
18912 trans.reset();
18913
18914 // One 401 report for the auth challenge, then a 200 report for the successful
18915 // retry. Note that we don't report the error draining the body, as the first
18916 // request already generated a report for the auth challenge.
18917 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18918
18919 // Check error report contents
18920 CheckReport(0 /* index */, 401 /* status_code */, OK);
18921 CheckReport(1 /* index */, 200 /* status_code */, OK);
18922
18923 const NetworkErrorLoggingService::RequestDetails& error1 =
18924 network_error_logging_service()->errors()[0];
18925 const NetworkErrorLoggingService::RequestDetails& error2 =
18926 network_error_logging_service()->errors()[1];
18927
18928 // Sanity-check elapsed time values
18929 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18930 // Check that the start time is refreshed when restarting with auth.
18931 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18932}
18933
18934TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18935 CreateReportRetryKeepAliveConnectionReset) {
18936 std::string extra_header_string = extra_headers_.ToString();
18937 MockWrite data_writes1[] = {
18938 MockWrite("GET / HTTP/1.1\r\n"
18939 "Host: www.example.org\r\n"
18940 "Connection: keep-alive\r\n"),
18941 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18942 MockWrite("GET / HTTP/1.1\r\n"
18943 "Host: www.example.org\r\n"
18944 "Connection: keep-alive\r\n"),
18945 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18946 };
18947
18948 MockRead data_reads1[] = {
18949 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18950 MockRead("hello"),
18951 // Connection is reset
18952 MockRead(ASYNC, ERR_CONNECTION_RESET),
18953 };
18954
18955 // Successful retry
18956 MockRead data_reads2[] = {
18957 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18958 MockRead("world"),
18959 MockRead(ASYNC, OK),
18960 };
18961
18962 StaticSocketDataProvider data1(data_reads1, data_writes1);
18963 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
18964 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18965 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18966
18967 SSLSocketDataProvider ssl1(ASYNC, OK);
18968 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18969 SSLSocketDataProvider ssl2(ASYNC, OK);
18970 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18971
18972 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18973 auto trans1 =
18974 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18975
18976 TestCompletionCallback callback1;
18977
18978 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
18979 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18980
18981 std::string response_data;
18982 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
18983 EXPECT_EQ("hello", response_data);
18984
18985 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18986
18987 auto trans2 =
18988 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18989
18990 TestCompletionCallback callback2;
18991
18992 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
18993 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18994
18995 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
18996 EXPECT_EQ("world", response_data);
18997
18998 trans1.reset();
18999 trans2.reset();
19000
19001 // One OK report from first request, then a ERR_CONNECTION_RESET report from
19002 // the second request, then an OK report from the successful retry.
19003 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19004
19005 // Check error report contents
19006 CheckReport(0 /* index */, 200 /* status_code */, OK);
19007 CheckReport(1 /* index */, 0 /* status_code */, ERR_CONNECTION_RESET);
19008 CheckReport(2 /* index */, 200 /* status_code */, OK);
19009}
19010
19011TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19012 CreateReportRetryKeepAlive408) {
19013 std::string extra_header_string = extra_headers_.ToString();
19014 MockWrite data_writes1[] = {
19015 MockWrite("GET / HTTP/1.1\r\n"
19016 "Host: www.example.org\r\n"
19017 "Connection: keep-alive\r\n"),
19018 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19019 MockWrite("GET / HTTP/1.1\r\n"
19020 "Host: www.example.org\r\n"
19021 "Connection: keep-alive\r\n"),
19022 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19023 };
19024
19025 MockRead data_reads1[] = {
19026 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19027 MockRead("hello"),
19028 // 408 Request Timeout
19029 MockRead(SYNCHRONOUS,
19030 "HTTP/1.1 408 Request Timeout\r\n"
19031 "Connection: Keep-Alive\r\n"
19032 "Content-Length: 6\r\n\r\n"
19033 "Pickle"),
19034 };
19035
19036 // Successful retry
19037 MockRead data_reads2[] = {
19038 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19039 MockRead("world"),
19040 MockRead(ASYNC, OK),
19041 };
19042
19043 StaticSocketDataProvider data1(data_reads1, data_writes1);
19044 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
19045 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19046 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19047
19048 SSLSocketDataProvider ssl1(ASYNC, OK);
19049 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
19050 SSLSocketDataProvider ssl2(ASYNC, OK);
19051 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
19052
19053 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19054 auto trans1 =
19055 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19056
19057 TestCompletionCallback callback1;
19058
19059 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
19060 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19061
19062 std::string response_data;
19063 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19064 EXPECT_EQ("hello", response_data);
19065
19066 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19067
19068 auto trans2 =
19069 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19070
19071 TestCompletionCallback callback2;
19072
19073 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
19074 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19075
19076 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19077 EXPECT_EQ("world", response_data);
19078
19079 trans1.reset();
19080 trans2.reset();
19081
19082 // One 200 report from first request, then a 408 report from
19083 // the second request, then a 200 report from the successful retry.
19084 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19085
19086 // Check error report contents
19087 CheckReport(0 /* index */, 200 /* status_code */, OK);
19088 CheckReport(1 /* index */, 408 /* status_code */, OK);
19089 CheckReport(2 /* index */, 200 /* status_code */, OK);
19090}
19091
19092TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19093 CreateReportRetry421WithoutConnectionPooling) {
19094 // Two hosts resolve to the same IP address.
19095 const std::string ip_addr = "1.2.3.4";
19096 IPAddress ip;
19097 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
19098 IPEndPoint peer_addr = IPEndPoint(ip, 443);
19099
19100 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
19101 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
19102 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
19103
19104 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19105
19106 // Two requests on the first connection.
19107 spdy::SpdySerializedFrame req1(
19108 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
19109 spdy_util_.UpdateWithStreamDestruction(1);
19110 spdy::SpdySerializedFrame req2(
19111 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
19112 spdy::SpdySerializedFrame rst(
19113 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
19114 MockWrite writes1[] = {
19115 CreateMockWrite(req1, 0),
19116 CreateMockWrite(req2, 3),
19117 CreateMockWrite(rst, 6),
19118 };
19119
19120 // The first one succeeds, the second gets error 421 Misdirected Request.
19121 spdy::SpdySerializedFrame resp1(
19122 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
19123 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
19124 spdy::SpdyHeaderBlock response_headers;
19125 response_headers[spdy::kHttp2StatusHeader] = "421";
19126 spdy::SpdySerializedFrame resp2(
19127 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
19128 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
19129 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
19130
19131 MockConnect connect1(ASYNC, OK, peer_addr);
19132 SequencedSocketData data1(connect1, reads1, writes1);
19133 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19134
19135 AddSSLSocketData();
19136
19137 // Retry the second request on a second connection.
19138 SpdyTestUtil spdy_util2;
19139 spdy::SpdySerializedFrame req3(
19140 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
19141 MockWrite writes2[] = {
19142 CreateMockWrite(req3, 0),
19143 };
19144
19145 spdy::SpdySerializedFrame resp3(
19146 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
19147 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
19148 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
19149 MockRead(ASYNC, 0, 3)};
19150
19151 MockConnect connect2(ASYNC, OK, peer_addr);
19152 SequencedSocketData data2(connect2, reads2, writes2);
19153 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19154
19155 AddSSLSocketData();
19156
19157 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3319158 int rv = session_deps_.host_resolver->LoadIntoCache(
19159 HostPortPair("mail.example.com", 443), base::nullopt);
19160 EXPECT_THAT(rv, IsOk());
Lily Chenfec60d92019-01-24 01:16:4219161
19162 HttpRequestInfo request1;
19163 request1.method = "GET";
19164 request1.url = GURL("https://www.example.org/");
19165 request1.load_flags = 0;
19166 request1.traffic_annotation =
19167 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19168 auto trans1 =
19169 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19170
Eric Orthf4db66a2019-02-19 21:35:3319171 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219172 rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
19173 EXPECT_THAT(callback.GetResult(rv), IsOk());
19174
19175 const HttpResponseInfo* response = trans1->GetResponseInfo();
19176 ASSERT_TRUE(response);
19177 ASSERT_TRUE(response->headers);
19178 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19179 EXPECT_TRUE(response->was_fetched_via_spdy);
19180 EXPECT_TRUE(response->was_alpn_negotiated);
19181 std::string response_data;
19182 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19183 EXPECT_EQ("hello!", response_data);
19184
19185 trans1.reset();
19186
19187 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19188
19189 HttpRequestInfo request2;
19190 request2.method = "GET";
19191 request2.url = GURL("https://mail.example.org/");
19192 request2.load_flags = 0;
19193 request2.traffic_annotation =
19194 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19195 auto trans2 =
19196 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19197
19198 BoundTestNetLog log;
19199 rv = trans2->Start(&request2, callback.callback(), log.bound());
19200 EXPECT_THAT(callback.GetResult(rv), IsOk());
19201
19202 response = trans2->GetResponseInfo();
19203 ASSERT_TRUE(response);
19204 ASSERT_TRUE(response->headers);
19205 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19206 EXPECT_TRUE(response->was_fetched_via_spdy);
19207 EXPECT_TRUE(response->was_alpn_negotiated);
19208 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19209 EXPECT_EQ("hello!", response_data);
19210
19211 trans2.reset();
19212
19213 // One 200 report from the first request, then a 421 report from the
19214 // second request, then a 200 report from the successful retry.
19215 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19216
19217 // Check error report contents
19218 const NetworkErrorLoggingService::RequestDetails& error1 =
19219 network_error_logging_service()->errors()[0];
19220 EXPECT_EQ(GURL("https://www.example.org/"), error1.uri);
19221 EXPECT_TRUE(error1.referrer.is_empty());
19222 EXPECT_EQ("", error1.user_agent);
19223 EXPECT_EQ(ip, error1.server_ip);
19224 EXPECT_EQ("h2", error1.protocol);
19225 EXPECT_EQ("GET", error1.method);
19226 EXPECT_EQ(200, error1.status_code);
19227 EXPECT_EQ(OK, error1.type);
19228 EXPECT_EQ(0, error1.reporting_upload_depth);
19229
19230 const NetworkErrorLoggingService::RequestDetails& error2 =
19231 network_error_logging_service()->errors()[1];
19232 EXPECT_EQ(GURL("https://mail.example.org/"), error2.uri);
19233 EXPECT_TRUE(error2.referrer.is_empty());
19234 EXPECT_EQ("", error2.user_agent);
19235 EXPECT_EQ(ip, error2.server_ip);
19236 EXPECT_EQ("h2", error2.protocol);
19237 EXPECT_EQ("GET", error2.method);
19238 EXPECT_EQ(421, error2.status_code);
19239 EXPECT_EQ(OK, error2.type);
19240 EXPECT_EQ(0, error2.reporting_upload_depth);
19241
19242 const NetworkErrorLoggingService::RequestDetails& error3 =
19243 network_error_logging_service()->errors()[2];
19244 EXPECT_EQ(GURL("https://mail.example.org/"), error3.uri);
19245 EXPECT_TRUE(error3.referrer.is_empty());
19246 EXPECT_EQ("", error3.user_agent);
19247 EXPECT_EQ(ip, error3.server_ip);
19248 EXPECT_EQ("h2", error3.protocol);
19249 EXPECT_EQ("GET", error3.method);
19250 EXPECT_EQ(200, error3.status_code);
19251 EXPECT_EQ(OK, error3.type);
19252 EXPECT_EQ(0, error3.reporting_upload_depth);
Douglas Creageref5eecdc2018-11-09 20:50:3619253}
19254
Lily Chend3930e72019-03-01 19:31:1119255TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19256 CreateReportCancelAfterStart) {
19257 StaticSocketDataProvider data;
19258 data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
19259 session_deps_.socket_factory->AddSocketDataProvider(&data);
19260
19261 TestCompletionCallback callback;
19262 auto session = CreateSession(&session_deps_);
19263 auto trans =
19264 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19265 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19266 EXPECT_EQ(rv, ERR_IO_PENDING);
19267
19268 // Cancel after start.
19269 trans.reset();
19270
19271 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19272 CheckReport(0 /* index */, 0 /* status_code */, ERR_ABORTED,
19273 IPAddress() /* server_ip */);
19274}
19275
19276TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19277 CreateReportCancelBeforeReadingBody) {
19278 std::string extra_header_string = extra_headers_.ToString();
19279 MockWrite data_writes[] = {
19280 MockWrite("GET / HTTP/1.1\r\n"
19281 "Host: www.example.org\r\n"
19282 "Connection: keep-alive\r\n"),
19283 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19284 };
19285 MockRead data_reads[] = {
19286 MockRead("HTTP/1.0 200 OK\r\n"),
19287 MockRead("Content-Length: 100\r\n\r\n"), // Body is never read.
19288 };
19289
19290 StaticSocketDataProvider data(data_reads, data_writes);
19291 session_deps_.socket_factory->AddSocketDataProvider(&data);
19292
19293 SSLSocketDataProvider ssl(ASYNC, OK);
19294 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19295
19296 TestCompletionCallback callback;
19297 auto session = CreateSession(&session_deps_);
19298 auto trans =
19299 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19300 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19301 EXPECT_THAT(callback.GetResult(rv), IsOk());
19302
19303 const HttpResponseInfo* response = trans->GetResponseInfo();
19304 ASSERT_TRUE(response);
19305
19306 EXPECT_TRUE(response->headers);
19307 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
19308
19309 // Cancel before reading the body.
19310 trans.reset();
19311
19312 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19313 CheckReport(0 /* index */, 200 /* status_code */, ERR_ABORTED);
19314}
19315
Lily Chen00196ab62018-12-04 19:52:2919316TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) {
19317 base::HistogramTester histograms;
19318 RequestPolicy();
19319 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19320 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19321
19322 // Make HTTP request
19323 std::string extra_header_string = extra_headers_.ToString();
19324 MockRead data_reads[] = {
19325 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
19326 MockRead("hello world"),
19327 MockRead(SYNCHRONOUS, OK),
19328 };
19329 MockWrite data_writes[] = {
19330 MockWrite("GET / HTTP/1.1\r\n"
19331 "Host: www.example.org\r\n"
19332 "Connection: keep-alive\r\n"),
19333 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19334 };
19335
Lily Chend3930e72019-03-01 19:31:1119336 StaticSocketDataProvider data(data_reads, data_writes);
19337 session_deps_.socket_factory->AddSocketDataProvider(&data);
Lily Chen00196ab62018-12-04 19:52:2919338
Lily Chenfec60d92019-01-24 01:16:4219339 // Insecure url
19340 url_ = "http://www.example.org/";
19341 request_.url = GURL(url_);
19342
Lily Chen00196ab62018-12-04 19:52:2919343 TestCompletionCallback callback;
19344 auto session = CreateSession(&session_deps_);
Lily Chenfec60d92019-01-24 01:16:4219345 auto trans =
19346 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19347 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19348 EXPECT_THAT(callback.GetResult(rv), IsOk());
19349
19350 std::string response_data;
19351 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19352 EXPECT_EQ("hello world", response_data);
Lily Chen00196ab62018-12-04 19:52:2919353
19354 // Insecure request does not generate a report
19355 histograms.ExpectBucketCount(
19356 NetworkErrorLoggingService::kRequestOutcomeHistogram,
Tsuyoshi Horo0b042232019-03-06 01:11:0519357 NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1);
Lily Chen00196ab62018-12-04 19:52:2919358
19359 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19360}
19361
19362TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19363 DontCreateReportHttpError) {
19364 base::HistogramTester histograms;
19365 RequestPolicy();
19366 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19367 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19368
19369 // Make HTTP request that fails
19370 MockRead data_reads[] = {
19371 MockRead("hello world"),
19372 MockRead(SYNCHRONOUS, OK),
19373 };
19374
19375 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
19376 session_deps_.socket_factory->AddSocketDataProvider(&data);
19377
Lily Chenfec60d92019-01-24 01:16:4219378 url_ = "http://www.originwithoutpolicy.com:2000/";
19379 request_.url = GURL(url_);
19380
Lily Chen00196ab62018-12-04 19:52:2919381 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19382
Lily Chen00196ab62018-12-04 19:52:2919383 auto trans =
19384 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Lily Chen00196ab62018-12-04 19:52:2919385 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219386 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
Lily Chen00196ab62018-12-04 19:52:2919387 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
19388
19389 // Insecure request does not generate a report, regardless of existence of a
19390 // policy for the origin.
19391 histograms.ExpectBucketCount(
19392 NetworkErrorLoggingService::kRequestOutcomeHistogram,
Tsuyoshi Horo0b042232019-03-06 01:11:0519393 NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1);
Lily Chen00196ab62018-12-04 19:52:2919394
19395 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19396}
19397
Lily Chen90ae93cc2019-02-14 01:15:3919398// Don't report on proxy auth challenges, don't report if connecting through a
19399// proxy.
19400TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportProxy) {
19401 HttpRequestInfo request;
19402 request.method = "GET";
19403 request.url = GURL("https://www.example.org/");
19404 request.traffic_annotation =
19405 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19406
19407 // Configure against proxy server "myproxy:70".
19408 session_deps_.proxy_resolution_service =
19409 ProxyResolutionService::CreateFixedFromPacResult(
19410 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
19411 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19412
19413 // Since we have proxy, should try to establish tunnel.
19414 MockWrite data_writes1[] = {
19415 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19416 "Host: www.example.org:443\r\n"
19417 "Proxy-Connection: keep-alive\r\n\r\n"),
19418 };
19419
19420 // The proxy responds to the connect with a 407, using a non-persistent
19421 // connection.
19422 MockRead data_reads1[] = {
19423 // No credentials.
19424 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
19425 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19426 MockRead("Proxy-Connection: close\r\n\r\n"),
19427 };
19428
19429 MockWrite data_writes2[] = {
19430 // After calling trans->RestartWithAuth(), this is the request we should
19431 // be issuing -- the final header line contains the credentials.
19432 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19433 "Host: www.example.org:443\r\n"
19434 "Proxy-Connection: keep-alive\r\n"
19435 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19436
19437 MockWrite("GET / HTTP/1.1\r\n"
19438 "Host: www.example.org\r\n"
19439 "Connection: keep-alive\r\n\r\n"),
19440 };
19441
19442 MockRead data_reads2[] = {
19443 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
19444
19445 MockRead("HTTP/1.1 200 OK\r\n"),
19446 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19447 MockRead("Content-Length: 5\r\n\r\n"),
19448 MockRead(SYNCHRONOUS, "hello"),
19449 };
19450
19451 StaticSocketDataProvider data1(data_reads1, data_writes1);
19452 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19453 StaticSocketDataProvider data2(data_reads2, data_writes2);
19454 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19455 SSLSocketDataProvider ssl(ASYNC, OK);
19456 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19457
19458 TestCompletionCallback callback1;
19459
19460 auto trans =
19461 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19462
19463 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
19464 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19465
19466 const HttpResponseInfo* response = trans->GetResponseInfo();
19467 EXPECT_EQ(407, response->headers->response_code());
19468
19469 std::string response_data;
19470 rv = ReadTransaction(trans.get(), &response_data);
19471 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
19472
19473 // No NEL report is generated for the 407.
19474 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19475
19476 TestCompletionCallback callback2;
19477
19478 rv =
19479 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
19480 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19481
19482 response = trans->GetResponseInfo();
19483 EXPECT_EQ(200, response->headers->response_code());
19484
19485 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19486 EXPECT_EQ("hello", response_data);
19487
19488 trans.reset();
19489
19490 // No NEL report is generated because we are behind a proxy.
19491 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19492}
19493
Douglas Creageref5eecdc2018-11-09 20:50:3619494TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19495 ReportContainsUploadDepth) {
19496 reporting_upload_depth_ = 7;
Lily Chenfec60d92019-01-24 01:16:4219497 request_.reporting_upload_depth = reporting_upload_depth_;
Douglas Creageref5eecdc2018-11-09 20:50:3619498 RequestPolicy();
19499 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219500 const NetworkErrorLoggingService::RequestDetails& error =
19501 network_error_logging_service()->errors()[0];
Douglas Creageref5eecdc2018-11-09 20:50:3619502 EXPECT_EQ(7, error.reporting_upload_depth);
19503}
19504
Lily Chenfec60d92019-01-24 01:16:4219505TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportElapsedTime) {
19506 std::string extra_header_string = extra_headers_.ToString();
19507 static const base::TimeDelta kSleepDuration =
19508 base::TimeDelta::FromMilliseconds(10);
19509
19510 std::vector<MockWrite> data_writes = {
19511 MockWrite(ASYNC, 0,
19512 "GET / HTTP/1.1\r\n"
19513 "Host: www.example.org\r\n"
19514 "Connection: keep-alive\r\n"),
19515 MockWrite(ASYNC, 1, extra_header_string.data()),
19516 };
19517
19518 std::vector<MockRead> data_reads = {
19519 // Write one byte of the status line, followed by a pause.
19520 MockRead(ASYNC, 2, "H"),
19521 MockRead(ASYNC, ERR_IO_PENDING, 3),
19522 MockRead(ASYNC, 4, "TTP/1.1 200 OK\r\n\r\n"),
19523 MockRead(ASYNC, 5, "hello world"),
19524 MockRead(SYNCHRONOUS, OK, 6),
19525 };
19526
19527 SequencedSocketData data(data_reads, data_writes);
19528 session_deps_.socket_factory->AddSocketDataProvider(&data);
19529
19530 SSLSocketDataProvider ssl(ASYNC, OK);
19531 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19532
19533 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19534
19535 auto trans =
19536 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19537
19538 TestCompletionCallback callback;
19539
19540 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19541 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19542
19543 data.RunUntilPaused();
19544 ASSERT_TRUE(data.IsPaused());
19545 FastForwardBy(kSleepDuration);
19546 data.Resume();
19547
19548 EXPECT_THAT(callback.GetResult(rv), IsOk());
19549
19550 std::string response_data;
19551 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19552 EXPECT_EQ("hello world", response_data);
19553
19554 trans.reset();
19555
Douglas Creageref5eecdc2018-11-09 20:50:3619556 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219557
19558 CheckReport(0 /* index */, 200 /* status_code */, OK);
19559
19560 const NetworkErrorLoggingService::RequestDetails& error =
19561 network_error_logging_service()->errors()[0];
19562
19563 // Sanity-check elapsed time in error report
19564 EXPECT_EQ(kSleepDuration, error.elapsed_time);
Douglas Creageref5eecdc2018-11-09 20:50:3619565}
Lily Chenfec60d92019-01-24 01:16:4219566
Douglas Creager3cb042052018-11-06 23:08:5219567#endif // BUILDFLAG(ENABLE_REPORTING)
19568
Batalov Vladislava4e97a502019-04-11 15:35:2319569TEST_F(HttpNetworkTransactionTest, AlwaysFailRequestToCache) {
19570 HttpRequestInfo request;
19571 request.method = "GET";
19572 request.url = GURL("http://example.org/");
19573
19574 request.load_flags = LOAD_ONLY_FROM_CACHE;
19575
19576 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19577 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19578 TestCompletionCallback callback1;
19579 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
19580
19581 EXPECT_THAT(rv, IsError(ERR_CACHE_MISS));
19582}
19583
Steven Valdez1c1859172019-04-10 15:33:2819584TEST_F(HttpNetworkTransactionTest, ZeroRTTDoesntConfirm) {
19585 HttpRequestInfo request;
19586 request.method = "GET";
19587 request.url = GURL("https://www.example.org/");
19588 request.traffic_annotation =
19589 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19590
19591 MockWrite data_writes[] = {
19592 MockWrite("GET / HTTP/1.1\r\n"
19593 "Host: www.example.org\r\n"
19594 "Connection: keep-alive\r\n\r\n"),
19595 };
19596
19597 // The proxy responds to the connect with a 407, using a persistent
19598 // connection.
19599 MockRead data_reads[] = {
19600 MockRead("HTTP/1.1 200 OK\r\n"),
19601 MockRead("Content-Length: 1\r\n\r\n"),
19602 MockRead(SYNCHRONOUS, "1"),
19603 };
19604
19605 StaticSocketDataProvider data(data_reads, data_writes);
19606 session_deps_.socket_factory->AddSocketDataProvider(&data);
19607 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19608 ssl.confirm = MockConfirm(SYNCHRONOUS, OK);
19609 session_deps_.enable_early_data = true;
19610 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19611
19612 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19613
19614 TestCompletionCallback callback;
19615 auto trans =
19616 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19617
19618 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19619 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19620
19621 rv = callback.WaitForResult();
19622 EXPECT_THAT(rv, IsOk());
19623
19624 const HttpResponseInfo* response = trans->GetResponseInfo();
19625 ASSERT_TRUE(response);
19626 ASSERT_TRUE(response->headers);
19627 EXPECT_EQ(200, response->headers->response_code());
19628 EXPECT_EQ(1, response->headers->GetContentLength());
19629
19630 // Check that ConfirmHandshake wasn't called.
19631 ASSERT_FALSE(ssl.ConfirmDataConsumed());
19632 ASSERT_TRUE(ssl.WriteBeforeConfirm());
19633
19634 trans.reset();
19635
19636 session->CloseAllConnections();
19637}
19638
19639TEST_F(HttpNetworkTransactionTest, ZeroRTTSyncConfirmSyncWrite) {
19640 HttpRequestInfo request;
19641 request.method = "POST";
19642 request.url = GURL("https://www.example.org/");
19643 request.traffic_annotation =
19644 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19645
19646 MockWrite data_writes[] = {
19647 MockWrite(SYNCHRONOUS,
19648 "POST / HTTP/1.1\r\n"
19649 "Host: www.example.org\r\n"
19650 "Connection: keep-alive\r\n"
19651 "Content-Length: 0\r\n\r\n"),
19652 };
19653
19654 // The proxy responds to the connect with a 407, using a persistent
19655 // connection.
19656 MockRead data_reads[] = {
19657 MockRead("HTTP/1.1 200 OK\r\n"),
19658 MockRead("Content-Length: 1\r\n\r\n"),
19659 MockRead(SYNCHRONOUS, "1"),
19660 };
19661
19662 StaticSocketDataProvider data(data_reads, data_writes);
19663 session_deps_.socket_factory->AddSocketDataProvider(&data);
19664 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19665 ssl.confirm = MockConfirm(SYNCHRONOUS, OK);
19666 session_deps_.enable_early_data = true;
19667 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19668
19669 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19670
19671 TestCompletionCallback callback;
19672 auto trans =
19673 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19674
19675 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19676 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19677
19678 rv = callback.WaitForResult();
19679 EXPECT_THAT(rv, IsOk());
19680
19681 const HttpResponseInfo* response = trans->GetResponseInfo();
19682 ASSERT_TRUE(response);
19683 ASSERT_TRUE(response->headers);
19684 EXPECT_EQ(200, response->headers->response_code());
19685 EXPECT_EQ(1, response->headers->GetContentLength());
19686
19687 // Check that the Write didn't get called before ConfirmHandshake completed.
19688 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19689
19690 trans.reset();
19691
19692 session->CloseAllConnections();
19693}
19694
19695TEST_F(HttpNetworkTransactionTest, ZeroRTTSyncConfirmAsyncWrite) {
19696 HttpRequestInfo request;
19697 request.method = "POST";
19698 request.url = GURL("https://www.example.org/");
19699 request.traffic_annotation =
19700 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19701
19702 MockWrite data_writes[] = {
19703 MockWrite(ASYNC,
19704 "POST / HTTP/1.1\r\n"
19705 "Host: www.example.org\r\n"
19706 "Connection: keep-alive\r\n"
19707 "Content-Length: 0\r\n\r\n"),
19708 };
19709
19710 // The proxy responds to the connect with a 407, using a persistent
19711 // connection.
19712 MockRead data_reads[] = {
19713 MockRead("HTTP/1.1 200 OK\r\n"),
19714 MockRead("Content-Length: 1\r\n\r\n"),
19715 MockRead(SYNCHRONOUS, "1"),
19716 };
19717
19718 StaticSocketDataProvider data(data_reads, data_writes);
19719 session_deps_.socket_factory->AddSocketDataProvider(&data);
19720 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19721 ssl.confirm = MockConfirm(SYNCHRONOUS, OK);
19722 session_deps_.enable_early_data = true;
19723 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19724
19725 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19726
19727 TestCompletionCallback callback;
19728 auto trans =
19729 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19730
19731 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19732 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19733
19734 rv = callback.WaitForResult();
19735 EXPECT_THAT(rv, IsOk());
19736
19737 const HttpResponseInfo* response = trans->GetResponseInfo();
19738 ASSERT_TRUE(response);
19739 ASSERT_TRUE(response->headers);
19740 EXPECT_EQ(200, response->headers->response_code());
19741 EXPECT_EQ(1, response->headers->GetContentLength());
19742
19743 // Check that the Write didn't get called before ConfirmHandshake completed.
19744 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19745
19746 trans.reset();
19747
19748 session->CloseAllConnections();
19749}
19750
19751TEST_F(HttpNetworkTransactionTest, ZeroRTTAsyncConfirmSyncWrite) {
19752 HttpRequestInfo request;
19753 request.method = "POST";
19754 request.url = GURL("https://www.example.org/");
19755 request.traffic_annotation =
19756 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19757
19758 MockWrite data_writes[] = {
19759 MockWrite(SYNCHRONOUS,
19760 "POST / HTTP/1.1\r\n"
19761 "Host: www.example.org\r\n"
19762 "Connection: keep-alive\r\n"
19763 "Content-Length: 0\r\n\r\n"),
19764 };
19765
19766 // The proxy responds to the connect with a 407, using a persistent
19767 // connection.
19768 MockRead data_reads[] = {
19769 MockRead("HTTP/1.1 200 OK\r\n"),
19770 MockRead("Content-Length: 1\r\n\r\n"),
19771 MockRead(SYNCHRONOUS, "1"),
19772 };
19773
19774 StaticSocketDataProvider data(data_reads, data_writes);
19775 session_deps_.socket_factory->AddSocketDataProvider(&data);
19776 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19777 ssl.confirm = MockConfirm(ASYNC, OK);
19778 session_deps_.enable_early_data = true;
19779 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19780
19781 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19782
19783 TestCompletionCallback callback;
19784 auto trans =
19785 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19786
19787 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19788 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19789
19790 rv = callback.WaitForResult();
19791 EXPECT_THAT(rv, IsOk());
19792
19793 const HttpResponseInfo* response = trans->GetResponseInfo();
19794 ASSERT_TRUE(response);
19795 ASSERT_TRUE(response->headers);
19796 EXPECT_EQ(200, response->headers->response_code());
19797 EXPECT_EQ(1, response->headers->GetContentLength());
19798
19799 // Check that the Write didn't get called before ConfirmHandshake completed.
19800 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19801
19802 trans.reset();
19803
19804 session->CloseAllConnections();
19805}
19806
19807TEST_F(HttpNetworkTransactionTest, ZeroRTTAsyncConfirmAsyncWrite) {
19808 HttpRequestInfo request;
19809 request.method = "POST";
19810 request.url = GURL("https://www.example.org/");
19811 request.traffic_annotation =
19812 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19813
19814 MockWrite data_writes[] = {
19815 MockWrite(ASYNC,
19816 "POST / HTTP/1.1\r\n"
19817 "Host: www.example.org\r\n"
19818 "Connection: keep-alive\r\n"
19819 "Content-Length: 0\r\n\r\n"),
19820 };
19821
19822 // The proxy responds to the connect with a 407, using a persistent
19823 // connection.
19824 MockRead data_reads[] = {
19825 MockRead("HTTP/1.1 200 OK\r\n"),
19826 MockRead("Content-Length: 1\r\n\r\n"),
19827 MockRead(SYNCHRONOUS, "1"),
19828 };
19829
19830 StaticSocketDataProvider data(data_reads, data_writes);
19831 session_deps_.socket_factory->AddSocketDataProvider(&data);
19832 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19833 ssl.confirm = MockConfirm(ASYNC, OK);
19834 session_deps_.enable_early_data = true;
19835 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19836
19837 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19838
19839 TestCompletionCallback callback;
19840 auto trans =
19841 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19842
19843 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19844 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19845
19846 rv = callback.WaitForResult();
19847 EXPECT_THAT(rv, IsOk());
19848
19849 const HttpResponseInfo* response = trans->GetResponseInfo();
19850 ASSERT_TRUE(response);
19851 ASSERT_TRUE(response->headers);
19852 EXPECT_EQ(200, response->headers->response_code());
19853 EXPECT_EQ(1, response->headers->GetContentLength());
19854
19855 // Check that the Write didn't get called before ConfirmHandshake completed.
19856 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19857
19858 trans.reset();
19859
19860 session->CloseAllConnections();
19861}
19862
19863TEST_F(HttpNetworkTransactionTest, ZeroRTTConfirmErrorSync) {
19864 HttpRequestInfo request;
19865 request.method = "POST";
19866 request.url = GURL("https://www.example.org/");
19867 request.traffic_annotation =
19868 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19869
19870 MockWrite data_writes[] = {
19871 MockWrite("POST / HTTP/1.1\r\n"
19872 "Host: www.example.org\r\n"
19873 "Connection: keep-alive\r\n"
19874 "Content-Length: 0\r\n\r\n"),
19875 };
19876
19877 // The proxy responds to the connect with a 407, using a persistent
19878 // connection.
19879 MockRead data_reads[] = {
19880 MockRead("HTTP/1.1 200 OK\r\n"),
19881 MockRead("Content-Length: 1\r\n\r\n"),
19882 MockRead(SYNCHRONOUS, "1"),
19883 };
19884
19885 StaticSocketDataProvider data(data_reads, data_writes);
19886 session_deps_.socket_factory->AddSocketDataProvider(&data);
19887 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19888 ssl.confirm = MockConfirm(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR);
19889 session_deps_.enable_early_data = true;
19890 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19891
19892 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19893
19894 TestCompletionCallback callback;
19895 auto trans =
19896 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19897
19898 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19899 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19900
19901 rv = callback.WaitForResult();
19902 EXPECT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
19903
19904 // Check that the Write didn't get called before ConfirmHandshake completed.
19905 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19906
19907 trans.reset();
19908
19909 session->CloseAllConnections();
19910}
19911
19912TEST_F(HttpNetworkTransactionTest, ZeroRTTConfirmErrorAsync) {
19913 HttpRequestInfo request;
19914 request.method = "POST";
19915 request.url = GURL("https://www.example.org/");
19916 request.traffic_annotation =
19917 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19918
19919 MockWrite data_writes[] = {
19920 MockWrite("POST / HTTP/1.1\r\n"
19921 "Host: www.example.org\r\n"
19922 "Connection: keep-alive\r\n"
19923 "Content-Length: 0\r\n\r\n"),
19924 };
19925
19926 // The proxy responds to the connect with a 407, using a persistent
19927 // connection.
19928 MockRead data_reads[] = {
19929 MockRead("HTTP/1.1 200 OK\r\n"),
19930 MockRead("Content-Length: 1\r\n\r\n"),
19931 MockRead(SYNCHRONOUS, "1"),
19932 };
19933
19934 StaticSocketDataProvider data(data_reads, data_writes);
19935 session_deps_.socket_factory->AddSocketDataProvider(&data);
19936 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19937 ssl.confirm = MockConfirm(ASYNC, ERR_SSL_PROTOCOL_ERROR);
19938 session_deps_.enable_early_data = true;
19939 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19940
19941 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19942
19943 TestCompletionCallback callback;
19944 auto trans =
19945 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19946
19947 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19948 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19949
19950 rv = callback.WaitForResult();
19951 EXPECT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
19952
19953 // Check that the Write didn't get called before ConfirmHandshake completed.
19954 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19955
19956 trans.reset();
19957
19958 session->CloseAllConnections();
19959}
19960
[email protected]89ceba9a2009-03-21 03:46:0619961} // namespace net