blob: 2da31ccd3cdc7d1df93db4a4197f2efb000272c7 [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"
tbansal28e68f82016-02-04 02:56:1547#include "net/base/proxy_delegate.h"
Lily Houghton582d4622018-01-22 22:43:4048#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3149#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5250#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1551#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0652#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2153#include "net/base/upload_file_element_reader.h"
Bence Béky230ac612017-08-30 19:17:0854#include "net/cert/cert_status_flags.h"
[email protected]6e7845ae2013-03-29 21:48:1155#include "net/cert/mock_cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5356#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2457#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1258#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0059#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2960#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1961#include "net/http/http_auth_scheme.h"
[email protected]0877e3d2009-10-17 22:29:5762#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5263#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5664#include "net/http/http_network_session_peer.h"
Matt Menke6e879bd2019-03-18 17:26:0465#include "net/http/http_proxy_connect_job.h"
Adam Rice425cf122015-01-19 06:18:2466#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1367#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5368#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5769#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3870#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1971#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0772#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0073#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1974#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5175#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4676#include "net/log/test_net_log_entry.h"
77#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4078#include "net/proxy_resolution/mock_proxy_resolver.h"
79#include "net/proxy_resolution/proxy_config_service_fixed.h"
80#include "net/proxy_resolution/proxy_info.h"
Lily Houghtonffe89daa02018-03-09 18:30:0381#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4082#include "net/proxy_resolution/proxy_resolver.h"
83#include "net/proxy_resolution/proxy_resolver_factory.h"
[email protected]f7984fc62009-06-22 23:26:4484#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1585#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0386#include "net/socket/client_socket_pool_manager.h"
Matt Menked6fd2a52019-03-20 06:14:3687#include "net/socket/connect_job.h"
ttuttle1f2d7e92015-04-28 16:17:4788#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0289#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0790#include "net/socket/next_proto.h"
Paul Jensena457017a2018-01-19 23:52:0491#include "net/socket/socket_tag.h"
[email protected]f7984fc62009-06-22 23:26:4492#include "net/socket/socket_test_util.h"
Matt Menke4b412da2019-01-25 19:31:1293#include "net/socket/socks_connect_job.h"
[email protected]f7984fc62009-06-22 23:26:4494#include "net/socket/ssl_client_socket.h"
Bence Béky94658bf2018-05-11 19:22:5895#include "net/spdy/spdy_session.h"
96#include "net/spdy/spdy_session_pool.h"
97#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1498#include "net/ssl/default_channel_id_store.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 */,
384 nullptr /* proxy_delegate */,
385 nullptr /* http_user_agent_settings */,
386 SSLClientSocketContext(),
387 SSLClientSocketContext(),
388 nullptr /* socket_performance_watcher_factory */,
389 nullptr /* network_quality_estimator */,
390 nullptr /* net_log */,
391 nullptr /* websocket_endpoint_lock_manager */),
Andrew Comminos517a92c2019-01-14 17:49:56392 ssl_(ASYNC, OK),
bnc032658ba2016-09-26 18:17:15393 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03394 HttpNetworkSession::NORMAL_SOCKET_POOL)),
395 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
396 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28397 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03398 }
[email protected]bb88e1d32013-05-03 23:11:07399
[email protected]e3ceb682011-06-28 23:55:46400 struct SimpleGetHelperResult {
401 int rv;
402 std::string status_line;
403 std::string response_data;
sclittlefb249892015-09-10 21:33:22404 int64_t total_received_bytes;
405 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25406 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47407 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59408 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46409 };
410
dcheng67be2b1f2014-10-27 21:47:29411 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50412 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55413 base::RunLoop().RunUntilIdle();
Andrew Comminos517a92c2019-01-14 17:49:56414 // Set an initial delay to ensure that the first call to TimeTicks::Now()
415 // before incrementing the counter does not return a null value.
416 FastForwardBy(TimeDelta::FromSeconds(1));
[email protected]2ff8b312010-04-26 22:20:54417 }
418
dcheng67be2b1f2014-10-27 21:47:29419 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50420 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55421 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09422 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55423 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09424 PlatformTest::TearDown();
[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 }
428
Andrew Comminos1f2ff1cc2018-12-14 05:22:38429 void Check100ResponseTiming(bool use_spdy);
430
[email protected]202965992011-12-07 23:04:51431 // Either |write_failure| specifies a write failure or |read_failure|
432 // specifies a read failure when using a reused socket. In either case, the
433 // failure should cause the network transaction to resend the request, and the
434 // other argument should be NULL.
435 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
436 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52437
[email protected]a34f61ee2014-03-18 20:59:49438 // Either |write_failure| specifies a write failure or |read_failure|
439 // specifies a read failure when using a reused socket. In either case, the
440 // failure should cause the network transaction to resend the request, and the
441 // other argument should be NULL.
442 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10443 const MockRead* read_failure,
444 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49445
Ryan Sleevib8d7ea02018-05-07 20:01:01446 SimpleGetHelperResult SimpleGetHelperForData(
447 base::span<StaticSocketDataProvider*> providers) {
[email protected]ff007e162009-05-23 09:13:15448 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52449
[email protected]ff007e162009-05-23 09:13:15450 HttpRequestInfo request;
451 request.method = "GET";
bncce36dca22015-04-21 22:11:23452 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10453 request.traffic_annotation =
454 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52455
vishal.b62985ca92015-04-17 08:45:51456 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07457 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09458 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16459 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27460
Ryan Sleevib8d7ea02018-05-07 20:01:01461 for (auto* provider : providers) {
462 session_deps_.socket_factory->AddSocketDataProvider(provider);
[email protected]5a60c8b2011-10-19 20:14:29463 }
initial.commit586acc5fe2008-07-26 22:42:52464
[email protected]49639fa2011-12-20 23:22:41465 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52466
eroman24bc6a12015-05-06 19:55:48467 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16468 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01469 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52470
[email protected]ff007e162009-05-23 09:13:15471 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16472 out.total_received_bytes = trans.GetTotalReceivedBytes();
473 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25474
475 // Even in the failure cases that use this function, connections are always
476 // successfully established before the error.
bnc691fda62016-08-12 00:43:16477 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25478 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
479
[email protected]ff007e162009-05-23 09:13:15480 if (out.rv != OK)
481 return out;
482
bnc691fda62016-08-12 00:43:16483 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50484 // Can't use ASSERT_* inside helper functions like this, so
485 // return an error.
wezca1070932016-05-26 20:30:52486 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50487 out.rv = ERR_UNEXPECTED;
488 return out;
489 }
[email protected]ff007e162009-05-23 09:13:15490 out.status_line = response->headers->GetStatusLine();
491
Tsuyoshi Horo01faed62019-02-20 22:11:37492 EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
493 EXPECT_EQ(80, response->remote_endpoint.port());
[email protected]6d81b482011-02-22 19:47:19494
ttuttled9dbc652015-09-29 20:00:59495 bool got_endpoint =
bnc691fda62016-08-12 00:43:16496 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59497 EXPECT_EQ(got_endpoint,
498 out.remote_endpoint_after_start.address().size() > 0);
499
bnc691fda62016-08-12 00:43:16500 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01501 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40502
mmenke43758e62015-05-04 21:09:46503 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40504 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39505 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00506 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
507 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39508 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00509 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
510 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15511
[email protected]f3da152d2012-06-02 01:00:57512 std::string line;
513 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
514 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
515
[email protected]79e1fd62013-06-20 06:50:04516 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16517 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04518 std::string value;
519 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23520 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04521 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
522 EXPECT_EQ("keep-alive", value);
523
524 std::string response_headers;
525 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23526 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04527 response_headers);
[email protected]3deb9a52010-11-11 00:24:40528
bnc691fda62016-08-12 00:43:16529 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22530 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16531 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22532
bnc691fda62016-08-12 00:43:16533 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47534 return out;
[email protected]ff007e162009-05-23 09:13:15535 }
initial.commit586acc5fe2008-07-26 22:42:52536
Ryan Sleevib8d7ea02018-05-07 20:01:01537 SimpleGetHelperResult SimpleGetHelper(base::span<const MockRead> data_reads) {
sclittlefb249892015-09-10 21:33:22538 MockWrite data_writes[] = {
539 MockWrite("GET / HTTP/1.1\r\n"
540 "Host: www.example.org\r\n"
541 "Connection: keep-alive\r\n\r\n"),
542 };
[email protected]5a60c8b2011-10-19 20:14:29543
Ryan Sleevib8d7ea02018-05-07 20:01:01544 StaticSocketDataProvider reads(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:22545 StaticSocketDataProvider* data[] = {&reads};
Ryan Sleevib8d7ea02018-05-07 20:01:01546 SimpleGetHelperResult out = SimpleGetHelperForData(data);
sclittlefb249892015-09-10 21:33:22547
Ryan Sleevib8d7ea02018-05-07 20:01:01548 EXPECT_EQ(CountWriteBytes(data_writes), out.total_sent_bytes);
sclittlefb249892015-09-10 21:33:22549 return out;
[email protected]b8015c42013-12-24 15:18:19550 }
551
bnc032658ba2016-09-26 18:17:15552 void AddSSLSocketData() {
553 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49554 ssl_.ssl_info.cert =
555 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
556 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15557 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
558 }
559
[email protected]ff007e162009-05-23 09:13:15560 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
561 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52562
[email protected]ff007e162009-05-23 09:13:15563 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07564
[email protected]bb88e1d32013-05-03 23:11:07565 void CheckErrorIsPassedBack(int error, IoMode mode);
566
Matt Menked6fd2a52019-03-20 06:14:36567 const CommonConnectJobParams dummy_connect_job_params_;
568
Douglas Creager134b52e2018-11-09 18:00:14569 // These clocks are defined here, even though they're only used in the
570 // Reporting tests below, since they need to be destroyed after
571 // |session_deps_|.
572 base::SimpleTestClock clock_;
573 base::SimpleTestTickClock tick_clock_;
574
[email protected]4bd46222013-05-14 19:32:23575 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07576 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15577 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03578
579 // Original socket limits. Some tests set these. Safest to always restore
580 // them once each test has been run.
581 int old_max_group_sockets_;
582 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15583};
[email protected]231d5a32008-09-13 00:45:27584
[email protected]448d4ca52012-03-04 04:12:23585namespace {
586
ryansturm49a8cb12016-06-15 16:51:09587class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27588 public:
ryansturm49a8cb12016-06-15 16:51:09589 BeforeHeadersSentHandler()
590 : observed_before_headers_sent_with_proxy_(false),
591 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27592
ryansturm49a8cb12016-06-15 16:51:09593 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
594 HttpRequestHeaders* request_headers) {
595 observed_before_headers_sent_ = true;
596 if (!proxy_info.is_http() && !proxy_info.is_https() &&
597 !proxy_info.is_quic()) {
598 return;
599 }
600 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27601 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
602 }
603
ryansturm49a8cb12016-06-15 16:51:09604 bool observed_before_headers_sent_with_proxy() const {
605 return observed_before_headers_sent_with_proxy_;
606 }
607
608 bool observed_before_headers_sent() const {
609 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27610 }
611
612 std::string observed_proxy_server_uri() const {
613 return observed_proxy_server_uri_;
614 }
615
616 private:
ryansturm49a8cb12016-06-15 16:51:09617 bool observed_before_headers_sent_with_proxy_;
618 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27619 std::string observed_proxy_server_uri_;
620
ryansturm49a8cb12016-06-15 16:51:09621 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27622};
623
[email protected]15a5ccf82008-10-23 19:57:43624// Fill |str| with a long header list that consumes >= |size| bytes.
625void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51626 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19627 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
628 const int sizeof_row = strlen(row);
629 const int num_rows = static_cast<int>(
630 ceil(static_cast<float>(size) / sizeof_row));
631 const int sizeof_data = num_rows * sizeof_row;
632 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43633 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51634
[email protected]4ddaf2502008-10-23 18:26:19635 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43636 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19637}
638
thakis84dff942015-07-28 20:47:38639#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09640uint64_t MockGetMSTime() {
641 // Tue, 23 May 2017 20:13:07 +0000
642 return 131400439870000000;
643}
644
[email protected]385a4672009-03-11 22:21:29645// Alternative functions that eliminate randomness and dependency on the local
646// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37647void MockGenerateRandom(uint8_t* output, size_t n) {
648 // This is set to 0xaa because the client challenge for testing in
649 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
650 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29651}
652
[email protected]fe2bc6a2009-03-23 16:52:20653std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37654 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29655}
thakis84dff942015-07-28 20:47:38656#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29657
Matt Menked6fd2a52019-03-20 06:14:36658class CaptureGroupIdTransportSocketPool : public TransportClientSocketPool {
[email protected]04e5be32009-06-26 20:00:31659 public:
Matt Menked6fd2a52019-03-20 06:14:36660 explicit CaptureGroupIdTransportSocketPool(
661 const CommonConnectJobParams* common_connect_job_params)
662 : TransportClientSocketPool(0,
663 0,
664 base::TimeDelta(),
665 common_connect_job_params,
666 nullptr /* ssl_config_service */) {}
[email protected]e60e47a2010-07-14 03:37:18667
Matt Menkef6edce752019-03-19 17:21:56668 const ClientSocketPool::GroupId& last_group_id_received() const {
669 return last_group_id_;
[email protected]d80a4322009-08-14 07:07:49670 }
671
Tarun Bansal162eabe52018-01-20 01:16:39672 bool socket_requested() const { return socket_requested_; }
673
Matt Menke28ac03e2019-02-25 22:25:50674 int RequestSocket(
Matt Menkef6edce752019-03-19 17:21:56675 const ClientSocketPool::GroupId& group_id,
Matt Menke28ac03e2019-02-25 22:25:50676 const void* socket_params,
677 RequestPriority priority,
678 const SocketTag& socket_tag,
679 ClientSocketPool::RespectLimits respect_limits,
680 ClientSocketHandle* handle,
681 CompletionOnceCallback callback,
682 const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback,
683 const NetLogWithSource& net_log) override {
Matt Menkef6edce752019-03-19 17:21:56684 last_group_id_ = group_id;
Tarun Bansal162eabe52018-01-20 01:16:39685 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31686 return ERR_IO_PENDING;
687 }
Matt Menkef6edce752019-03-19 17:21:56688 void CancelRequest(const ClientSocketPool::GroupId& group_id,
dmichaeld6e570d2014-12-18 22:30:57689 ClientSocketHandle* handle) override {}
Matt Menkef6edce752019-03-19 17:21:56690 void ReleaseSocket(const ClientSocketPool::GroupId& group_id,
danakj1fd259a02016-04-16 03:17:09691 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57692 int id) override {}
693 void CloseIdleSockets() override {}
Matt Menkef6edce752019-03-19 17:21:56694 void CloseIdleSocketsInGroup(
695 const ClientSocketPool::GroupId& group_id) override {}
dmichaeld6e570d2014-12-18 22:30:57696 int IdleSocketCount() const override { return 0; }
Matt Menkef6edce752019-03-19 17:21:56697 size_t IdleSocketCountInGroup(
698 const ClientSocketPool::GroupId& group_id) const override {
[email protected]04e5be32009-06-26 20:00:31699 return 0;
700 }
Matt Menkef6edce752019-03-19 17:21:56701 LoadState GetLoadState(const ClientSocketPool::GroupId& group_id,
dmichaeld6e570d2014-12-18 22:30:57702 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31703 return LOAD_STATE_IDLE;
704 }
[email protected]d80a4322009-08-14 07:07:49705
706 private:
Matt Menkef6edce752019-03-19 17:21:56707 ClientSocketPool::GroupId last_group_id_;
Tarun Bansal162eabe52018-01-20 01:16:39708 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31709};
710
[email protected]231d5a32008-09-13 00:45:27711//-----------------------------------------------------------------------------
712
[email protected]79cb5c12011-09-12 13:12:04713// Helper functions for validating that AuthChallengeInfo's are correctly
714// configured for common cases.
715bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
716 if (!auth_challenge)
717 return false;
718 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43719 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04720 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19721 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04722 return true;
723}
724
725bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
726 if (!auth_challenge)
727 return false;
728 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43729 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
730 EXPECT_EQ("MyRealm1", auth_challenge->realm);
731 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
732 return true;
733}
734
735bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
736 if (!auth_challenge)
737 return false;
738 EXPECT_TRUE(auth_challenge->is_proxy);
739 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04740 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19741 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04742 return true;
743}
744
745bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
746 if (!auth_challenge)
747 return false;
748 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43749 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04750 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19751 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04752 return true;
753}
754
thakis84dff942015-07-28 20:47:38755#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04756bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
757 if (!auth_challenge)
758 return false;
759 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55760 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04761 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19762 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04763 return true;
764}
David Benjamin5cb91132018-04-06 05:54:49765
766bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) {
767 if (!auth_challenge)
768 return false;
769 EXPECT_TRUE(auth_challenge->is_proxy);
770 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
771 EXPECT_EQ(std::string(), auth_challenge->realm);
772 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
773 return true;
774}
thakis84dff942015-07-28 20:47:38775#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04776
[email protected]448d4ca52012-03-04 04:12:23777} // namespace
778
bncd16676a2016-07-20 16:23:01779TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16781 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27782}
783
bncd16676a2016-07-20 16:23:01784TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27785 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35786 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
787 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06788 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27789 };
Ryan Sleevib8d7ea02018-05-07 20:01:01790 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01791 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27792 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
793 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01794 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22795 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47796 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59797
798 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27799}
800
801// Response with no status line.
bncd16676a2016-07-20 16:23:01802TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27803 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35804 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06805 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27806 };
Ryan Sleevib8d7ea02018-05-07 20:01:01807 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41808 EXPECT_THAT(out.rv, IsOk());
809 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
810 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01811 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41812 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27813}
814
mmenkea7da6da2016-09-01 21:56:52815// Response with no status line, and a weird port. Should fail by default.
816TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
817 MockRead data_reads[] = {
818 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
819 };
820
Ryan Sleevib8d7ea02018-05-07 20:01:01821 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52822 session_deps_.socket_factory->AddSocketDataProvider(&data);
823
824 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
825
krasinc06a72a2016-12-21 03:42:46826 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58827 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19828 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52829
mmenkea7da6da2016-09-01 21:56:52830 request.method = "GET";
831 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10832 request.traffic_annotation =
833 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
834
mmenkea7da6da2016-09-01 21:56:52835 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20836 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52837 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
838}
839
Shivani Sharmafdcaefd2017-11-02 00:12:26840// Tests that request info can be destroyed after the headers phase is complete.
841TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
842 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
843 auto trans =
844 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
845
846 MockRead data_reads[] = {
847 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
848 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
849 };
Ryan Sleevib8d7ea02018-05-07 20:01:01850 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Shivani Sharmafdcaefd2017-11-02 00:12:26851 session_deps_.socket_factory->AddSocketDataProvider(&data);
852
853 TestCompletionCallback callback;
854
855 {
856 auto request = std::make_unique<HttpRequestInfo>();
857 request->method = "GET";
858 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10859 request->traffic_annotation =
860 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26861
862 int rv =
863 trans->Start(request.get(), callback.callback(), NetLogWithSource());
864
865 EXPECT_THAT(callback.GetResult(rv), IsOk());
866 } // Let request info be destroyed.
867
868 trans.reset();
869}
870
mmenkea7da6da2016-09-01 21:56:52871// Response with no status line, and a weird port. Option to allow weird ports
872// enabled.
873TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
874 MockRead data_reads[] = {
875 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
876 };
877
Ryan Sleevib8d7ea02018-05-07 20:01:01878 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52879 session_deps_.socket_factory->AddSocketDataProvider(&data);
880 session_deps_.http_09_on_non_default_ports_enabled = true;
881 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
882
krasinc06a72a2016-12-21 03:42:46883 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58884 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19885 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52886
mmenkea7da6da2016-09-01 21:56:52887 request.method = "GET";
888 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10889 request.traffic_annotation =
890 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
891
mmenkea7da6da2016-09-01 21:56:52892 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20893 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52894 EXPECT_THAT(callback.GetResult(rv), IsOk());
895
896 const HttpResponseInfo* info = trans->GetResponseInfo();
897 ASSERT_TRUE(info->headers);
898 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
899
900 // Don't bother to read the body - that's verified elsewhere, important thing
901 // is that the option to allow HTTP/0.9 on non-default ports is respected.
902}
903
[email protected]231d5a32008-09-13 00:45:27904// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01905TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27906 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35907 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06908 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27909 };
Ryan Sleevib8d7ea02018-05-07 20:01:01910 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01911 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27912 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
913 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01914 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22915 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27916}
917
918// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01919TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27920 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35921 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06922 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27923 };
Ryan Sleevib8d7ea02018-05-07 20:01:01924 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01925 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27926 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
927 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01928 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22929 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27930}
931
932// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01933TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27934 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35935 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06936 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27937 };
Ryan Sleevib8d7ea02018-05-07 20:01:01938 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41939 EXPECT_THAT(out.rv, IsOk());
940 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
941 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01942 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41943 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27944}
945
946// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01947TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27948 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35949 MockRead("\n"),
950 MockRead("\n"),
951 MockRead("Q"),
952 MockRead("J"),
953 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06954 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27955 };
Ryan Sleevib8d7ea02018-05-07 20:01:01956 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01957 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27958 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
959 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01960 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22961 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27962}
963
964// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01965TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27966 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35967 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06968 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27969 };
Ryan Sleevib8d7ea02018-05-07 20:01:01970 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41971 EXPECT_THAT(out.rv, IsOk());
972 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
973 EXPECT_EQ("HTT", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01974 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41975 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52976}
977
[email protected]f9d44aa2008-09-23 23:57:17978// Simulate a 204 response, lacking a Content-Length header, sent over a
979// persistent connection. The response should still terminate since a 204
980// cannot have a response body.
bncd16676a2016-07-20 16:23:01981TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19982 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17983 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35984 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19985 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06986 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17987 };
Ryan Sleevib8d7ea02018-05-07 20:01:01988 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01989 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17990 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
991 EXPECT_EQ("", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01992 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22993 int64_t response_size = reads_size - strlen(junk);
994 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17995}
996
[email protected]0877e3d2009-10-17 22:29:57997// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:01998TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19999 std::string final_chunk = "0\r\n\r\n";
1000 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1001 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571002 MockRead data_reads[] = {
1003 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1004 MockRead("5\r\nHello\r\n"),
1005 MockRead("1\r\n"),
1006 MockRead(" \r\n"),
1007 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191008 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061009 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571010 };
Ryan Sleevib8d7ea02018-05-07 20:01:011011 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011012 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571013 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1014 EXPECT_EQ("Hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011015 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221016 int64_t response_size = reads_size - extra_data.size();
1017 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571018}
1019
[email protected]9fe44f52010-09-23 18:36:001020// Next tests deal with http://crbug.com/56344.
1021
bncd16676a2016-07-20 16:23:011022TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001023 MultipleContentLengthHeadersNoTransferEncoding) {
1024 MockRead data_reads[] = {
1025 MockRead("HTTP/1.1 200 OK\r\n"),
1026 MockRead("Content-Length: 10\r\n"),
1027 MockRead("Content-Length: 5\r\n\r\n"),
1028 };
Ryan Sleevib8d7ea02018-05-07 20:01:011029 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011030 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001031}
1032
bncd16676a2016-07-20 16:23:011033TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041034 DuplicateContentLengthHeadersNoTransferEncoding) {
1035 MockRead data_reads[] = {
1036 MockRead("HTTP/1.1 200 OK\r\n"),
1037 MockRead("Content-Length: 5\r\n"),
1038 MockRead("Content-Length: 5\r\n\r\n"),
1039 MockRead("Hello"),
1040 };
Ryan Sleevib8d7ea02018-05-07 20:01:011041 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011042 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041043 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1044 EXPECT_EQ("Hello", out.response_data);
1045}
1046
bncd16676a2016-07-20 16:23:011047TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041048 ComplexContentLengthHeadersNoTransferEncoding) {
1049 // More than 2 dupes.
1050 {
1051 MockRead data_reads[] = {
1052 MockRead("HTTP/1.1 200 OK\r\n"),
1053 MockRead("Content-Length: 5\r\n"),
1054 MockRead("Content-Length: 5\r\n"),
1055 MockRead("Content-Length: 5\r\n\r\n"),
1056 MockRead("Hello"),
1057 };
Ryan Sleevib8d7ea02018-05-07 20:01:011058 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011059 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041060 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1061 EXPECT_EQ("Hello", out.response_data);
1062 }
1063 // HTTP/1.0
1064 {
1065 MockRead data_reads[] = {
1066 MockRead("HTTP/1.0 200 OK\r\n"),
1067 MockRead("Content-Length: 5\r\n"),
1068 MockRead("Content-Length: 5\r\n"),
1069 MockRead("Content-Length: 5\r\n\r\n"),
1070 MockRead("Hello"),
1071 };
Ryan Sleevib8d7ea02018-05-07 20:01:011072 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011073 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041074 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1075 EXPECT_EQ("Hello", out.response_data);
1076 }
1077 // 2 dupes and one mismatched.
1078 {
1079 MockRead data_reads[] = {
1080 MockRead("HTTP/1.1 200 OK\r\n"),
1081 MockRead("Content-Length: 10\r\n"),
1082 MockRead("Content-Length: 10\r\n"),
1083 MockRead("Content-Length: 5\r\n\r\n"),
1084 };
Ryan Sleevib8d7ea02018-05-07 20:01:011085 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011086 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041087 }
1088}
1089
bncd16676a2016-07-20 16:23:011090TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001091 MultipleContentLengthHeadersTransferEncoding) {
1092 MockRead data_reads[] = {
1093 MockRead("HTTP/1.1 200 OK\r\n"),
1094 MockRead("Content-Length: 666\r\n"),
1095 MockRead("Content-Length: 1337\r\n"),
1096 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1097 MockRead("5\r\nHello\r\n"),
1098 MockRead("1\r\n"),
1099 MockRead(" \r\n"),
1100 MockRead("5\r\nworld\r\n"),
1101 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061102 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001103 };
Ryan Sleevib8d7ea02018-05-07 20:01:011104 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011105 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001106 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1107 EXPECT_EQ("Hello world", out.response_data);
1108}
1109
[email protected]1628fe92011-10-04 23:04:551110// Next tests deal with http://crbug.com/98895.
1111
1112// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011113TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551114 MockRead data_reads[] = {
1115 MockRead("HTTP/1.1 200 OK\r\n"),
1116 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1117 MockRead("Content-Length: 5\r\n\r\n"),
1118 MockRead("Hello"),
1119 };
Ryan Sleevib8d7ea02018-05-07 20:01:011120 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011121 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551122 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1123 EXPECT_EQ("Hello", out.response_data);
1124}
1125
[email protected]54a9c6e52012-03-21 20:10:591126// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011127TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551128 MockRead data_reads[] = {
1129 MockRead("HTTP/1.1 200 OK\r\n"),
1130 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1131 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1132 MockRead("Content-Length: 5\r\n\r\n"),
1133 MockRead("Hello"),
1134 };
Ryan Sleevib8d7ea02018-05-07 20:01:011135 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011136 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591137 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1138 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551139}
1140
1141// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011142TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551143 MockRead data_reads[] = {
1144 MockRead("HTTP/1.1 200 OK\r\n"),
1145 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1146 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1147 MockRead("Content-Length: 5\r\n\r\n"),
1148 MockRead("Hello"),
1149 };
Ryan Sleevib8d7ea02018-05-07 20:01:011150 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011151 EXPECT_THAT(out.rv,
1152 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551153}
1154
[email protected]54a9c6e52012-03-21 20:10:591155// Checks that two identical Location headers result in no error.
1156// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011157TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551158 MockRead data_reads[] = {
1159 MockRead("HTTP/1.1 302 Redirect\r\n"),
1160 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591161 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551162 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061163 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551164 };
1165
1166 HttpRequestInfo request;
1167 request.method = "GET";
1168 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101169 request.traffic_annotation =
1170 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551171
danakj1fd259a02016-04-16 03:17:091172 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161173 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551174
Ryan Sleevib8d7ea02018-05-07 20:01:011175 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071176 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551177
[email protected]49639fa2011-12-20 23:22:411178 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551179
tfarina42834112016-09-22 13:38:201180 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011181 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551182
robpercival214763f2016-07-01 23:27:011183 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551184
bnc691fda62016-08-12 00:43:161185 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521186 ASSERT_TRUE(response);
1187 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551188 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1189 std::string url;
1190 EXPECT_TRUE(response->headers->IsRedirect(&url));
1191 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471192 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551193}
1194
[email protected]1628fe92011-10-04 23:04:551195// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011196TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551197 MockRead data_reads[] = {
1198 MockRead("HTTP/1.1 302 Redirect\r\n"),
1199 MockRead("Location: http://good.com/\r\n"),
1200 MockRead("Location: http://evil.com/\r\n"),
1201 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061202 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551203 };
Ryan Sleevib8d7ea02018-05-07 20:01:011204 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011205 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551206}
1207
[email protected]ef0faf2e72009-03-05 23:27:231208// Do a request using the HEAD method. Verify that we don't try to read the
1209// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011210TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421211 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231212 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231213 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101214 request.traffic_annotation =
1215 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231216
danakj1fd259a02016-04-16 03:17:091217 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161218 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091219 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161220 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091221 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1222 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271223
[email protected]ef0faf2e72009-03-05 23:27:231224 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131225 MockWrite("HEAD / HTTP/1.1\r\n"
1226 "Host: www.example.org\r\n"
1227 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231228 };
1229 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231230 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1231 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231232
mmenked39192ee2015-12-09 00:57:231233 // No response body because the test stops reading here.
1234 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231235 };
1236
Ryan Sleevib8d7ea02018-05-07 20:01:011237 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:071238 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231239
[email protected]49639fa2011-12-20 23:22:411240 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231241
tfarina42834112016-09-22 13:38:201242 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011243 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231244
1245 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011246 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231247
bnc691fda62016-08-12 00:43:161248 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521249 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231250
1251 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521252 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231253 EXPECT_EQ(1234, response->headers->GetContentLength());
1254 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471255 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091256 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1257 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231258
1259 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101260 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231261 bool has_server_header = response->headers->EnumerateHeader(
1262 &iter, "Server", &server_header);
1263 EXPECT_TRUE(has_server_header);
1264 EXPECT_EQ("Blah", server_header);
1265
1266 // Reading should give EOF right away, since there is no message body
1267 // (despite non-zero content-length).
1268 std::string response_data;
bnc691fda62016-08-12 00:43:161269 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011270 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231271 EXPECT_EQ("", response_data);
1272}
1273
bncd16676a2016-07-20 16:23:011274TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091275 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521276
1277 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351278 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1279 MockRead("hello"),
1280 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1281 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061282 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521283 };
Ryan Sleevib8d7ea02018-05-07 20:01:011284 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071285 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521286
[email protected]0b0bf032010-09-21 18:08:501287 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521288 "hello", "world"
1289 };
1290
1291 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421292 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521293 request.method = "GET";
bncce36dca22015-04-21 22:11:231294 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101295 request.traffic_annotation =
1296 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521297
bnc691fda62016-08-12 00:43:161298 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271299
[email protected]49639fa2011-12-20 23:22:411300 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521301
tfarina42834112016-09-22 13:38:201302 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011303 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521304
1305 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011306 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521307
bnc691fda62016-08-12 00:43:161308 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521309 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521310
wezca1070932016-05-26 20:30:521311 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251312 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471313 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521314
1315 std::string response_data;
bnc691fda62016-08-12 00:43:161316 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011317 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251318 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521319 }
1320}
1321
bncd16676a2016-07-20 16:23:011322TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091323 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221324 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191325 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221326 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271327
[email protected]1c773ea12009-04-28 19:58:421328 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521329 request.method = "POST";
1330 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271331 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:101332 request.traffic_annotation =
1333 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521334
shivanishab9a143952016-09-19 17:23:411335 // Check the upload progress returned before initialization is correct.
1336 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1337 EXPECT_EQ(0u, progress.size());
1338 EXPECT_EQ(0u, progress.position());
1339
danakj1fd259a02016-04-16 03:17:091340 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161341 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271342
initial.commit586acc5fe2008-07-26 22:42:521343 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351344 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1345 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1346 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061347 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521348 };
Ryan Sleevib8d7ea02018-05-07 20:01:011349 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071350 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521351
[email protected]49639fa2011-12-20 23:22:411352 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521353
tfarina42834112016-09-22 13:38:201354 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011355 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521356
1357 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011358 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521359
bnc691fda62016-08-12 00:43:161360 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521361 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521362
wezca1070932016-05-26 20:30:521363 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251364 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521365
1366 std::string response_data;
bnc691fda62016-08-12 00:43:161367 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011368 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251369 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521370}
1371
[email protected]3a2d3662009-03-27 03:49:141372// This test is almost the same as Ignores100 above, but the response contains
1373// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571374// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011375TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421376 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141377 request.method = "GET";
1378 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101379 request.traffic_annotation =
1380 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141381
danakj1fd259a02016-04-16 03:17:091382 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161383 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271384
[email protected]3a2d3662009-03-27 03:49:141385 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571386 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1387 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141388 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061389 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141390 };
Ryan Sleevib8d7ea02018-05-07 20:01:011391 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071392 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141393
[email protected]49639fa2011-12-20 23:22:411394 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141395
tfarina42834112016-09-22 13:38:201396 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141398
1399 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011400 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141401
bnc691fda62016-08-12 00:43:161402 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521403 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141404
wezca1070932016-05-26 20:30:521405 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141406 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1407
1408 std::string response_data;
bnc691fda62016-08-12 00:43:161409 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011410 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141411 EXPECT_EQ("hello world", response_data);
1412}
1413
Andrew Comminos517a92c2019-01-14 17:49:561414TEST_F(HttpNetworkTransactionTest, LoadTimingMeasuresTimeToFirstByteForHttp) {
1415 static const base::TimeDelta kDelayAfterFirstByte =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381416 base::TimeDelta::FromMilliseconds(10);
1417
1418 HttpRequestInfo request;
1419 request.method = "GET";
1420 request.url = GURL("http://www.foo.com/");
1421 request.traffic_annotation =
1422 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1423
1424 std::vector<MockWrite> data_writes = {
1425 MockWrite(ASYNC, 0,
1426 "GET / HTTP/1.1\r\n"
1427 "Host: www.foo.com\r\n"
1428 "Connection: keep-alive\r\n\r\n"),
1429 };
1430
1431 std::vector<MockRead> data_reads = {
1432 // Write one byte of the status line, followed by a pause.
1433 MockRead(ASYNC, 1, "H"),
1434 MockRead(ASYNC, ERR_IO_PENDING, 2),
1435 MockRead(ASYNC, 3, "TTP/1.1 200 OK\r\n\r\n"),
1436 MockRead(ASYNC, 4, "hello world"),
1437 MockRead(SYNCHRONOUS, OK, 5),
1438 };
1439
1440 SequencedSocketData data(data_reads, data_writes);
1441 session_deps_.socket_factory->AddSocketDataProvider(&data);
1442
1443 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1444
1445 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1446
1447 TestCompletionCallback callback;
1448
1449 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1450 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1451
1452 data.RunUntilPaused();
1453 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561454 FastForwardBy(kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381455 data.Resume();
1456
1457 rv = callback.WaitForResult();
1458 EXPECT_THAT(rv, IsOk());
1459
1460 const HttpResponseInfo* response = trans.GetResponseInfo();
1461 ASSERT_TRUE(response);
1462
1463 EXPECT_TRUE(response->headers);
1464 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1465
1466 LoadTimingInfo load_timing_info;
1467 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1468 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1469 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561470 // Ensure we didn't include the delay in the TTFB time.
1471 EXPECT_EQ(load_timing_info.receive_headers_start,
1472 load_timing_info.connect_timing.connect_end);
1473 // Ensure that the mock clock advanced at all.
1474 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1475 kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381476
1477 std::string response_data;
1478 rv = ReadTransaction(&trans, &response_data);
1479 EXPECT_THAT(rv, IsOk());
1480 EXPECT_EQ("hello world", response_data);
1481}
1482
1483// Tests that the time-to-first-byte reported in a transaction's load timing
1484// info uses the first response, even if 1XX/informational.
1485void HttpNetworkTransactionTest::Check100ResponseTiming(bool use_spdy) {
Andrew Comminos517a92c2019-01-14 17:49:561486 static const base::TimeDelta kDelayAfter100Response =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381487 base::TimeDelta::FromMilliseconds(10);
1488
1489 HttpRequestInfo request;
1490 request.method = "GET";
1491 request.url = GURL("https://www.foo.com/");
1492 request.traffic_annotation =
1493 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1494
1495 SSLSocketDataProvider ssl(ASYNC, OK);
1496 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1497
1498 std::vector<MockWrite> data_writes;
1499 std::vector<MockRead> data_reads;
1500
1501 spdy::SpdySerializedFrame spdy_req(
1502 spdy_util_.ConstructSpdyGet(request.url.spec().c_str(), 1, LOWEST));
1503
1504 spdy::SpdyHeaderBlock spdy_resp1_headers;
1505 spdy_resp1_headers[spdy::kHttp2StatusHeader] = "100";
1506 spdy::SpdySerializedFrame spdy_resp1(
1507 spdy_util_.ConstructSpdyReply(1, spdy_resp1_headers.Clone()));
1508 spdy::SpdySerializedFrame spdy_resp2(
1509 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1510 spdy::SpdySerializedFrame spdy_data(
1511 spdy_util_.ConstructSpdyDataFrame(1, "hello world", true));
1512
1513 if (use_spdy) {
1514 ssl.next_proto = kProtoHTTP2;
1515
1516 data_writes = {CreateMockWrite(spdy_req, 0)};
1517
1518 data_reads = {
1519 CreateMockRead(spdy_resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
1520 CreateMockRead(spdy_resp2, 3), CreateMockRead(spdy_data, 4),
1521 MockRead(SYNCHRONOUS, OK, 5),
1522 };
1523 } else {
1524 data_writes = {
1525 MockWrite(ASYNC, 0,
1526 "GET / HTTP/1.1\r\n"
1527 "Host: www.foo.com\r\n"
1528 "Connection: keep-alive\r\n\r\n"),
1529 };
1530
1531 data_reads = {
1532 MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
1533 MockRead(ASYNC, ERR_IO_PENDING, 2),
1534
1535 MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1536 MockRead(ASYNC, 4, "hello world"),
1537 MockRead(SYNCHRONOUS, OK, 5),
1538 };
1539 }
1540
1541 SequencedSocketData data(data_reads, data_writes);
1542 session_deps_.socket_factory->AddSocketDataProvider(&data);
1543
1544 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1545
1546 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1547
1548 TestCompletionCallback callback;
1549
1550 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1551 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1552
1553 data.RunUntilPaused();
1554 // We should now have parsed the 100 response and hit ERR_IO_PENDING. Insert
1555 // the delay before parsing the 200 response.
1556 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561557 FastForwardBy(kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381558 data.Resume();
1559
1560 rv = callback.WaitForResult();
1561 EXPECT_THAT(rv, IsOk());
1562
1563 const HttpResponseInfo* response = trans.GetResponseInfo();
1564 ASSERT_TRUE(response);
1565
1566 LoadTimingInfo load_timing_info;
1567 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1568 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1569 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561570 // Ensure we didn't include the delay in the TTFB time.
1571 EXPECT_EQ(load_timing_info.receive_headers_start,
1572 load_timing_info.connect_timing.connect_end);
1573 // Ensure that the mock clock advanced at all.
1574 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1575 kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381576
1577 std::string response_data;
1578 rv = ReadTransaction(&trans, &response_data);
1579 EXPECT_THAT(rv, IsOk());
1580 EXPECT_EQ("hello world", response_data);
1581}
1582
Andrew Comminos517a92c2019-01-14 17:49:561583TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForHttp) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381584 Check100ResponseTiming(false /* use_spdy */);
1585}
1586
Andrew Comminos517a92c2019-01-14 17:49:561587TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForSpdy) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381588 Check100ResponseTiming(true /* use_spdy */);
1589}
1590
bncd16676a2016-07-20 16:23:011591TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081592 HttpRequestInfo request;
1593 request.method = "POST";
1594 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101595 request.traffic_annotation =
1596 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081597
danakj1fd259a02016-04-16 03:17:091598 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161599 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081600
1601 MockRead data_reads[] = {
1602 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1603 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381604 };
Ryan Sleevib8d7ea02018-05-07 20:01:011605 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
zmo9528c9f42015-08-04 22:12:081606 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381607
zmo9528c9f42015-08-04 22:12:081608 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381609
tfarina42834112016-09-22 13:38:201610 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011611 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381612
zmo9528c9f42015-08-04 22:12:081613 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011614 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381615
zmo9528c9f42015-08-04 22:12:081616 std::string response_data;
bnc691fda62016-08-12 00:43:161617 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011618 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081619 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381620}
1621
bncd16676a2016-07-20 16:23:011622TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381623 HttpRequestInfo request;
1624 request.method = "POST";
1625 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101626 request.traffic_annotation =
1627 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381628
danakj1fd259a02016-04-16 03:17:091629 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161630 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271631
[email protected]ee9410e72010-01-07 01:42:381632 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061633 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381634 };
Ryan Sleevib8d7ea02018-05-07 20:01:011635 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071636 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381637
[email protected]49639fa2011-12-20 23:22:411638 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381639
tfarina42834112016-09-22 13:38:201640 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011641 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381642
1643 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011644 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381645}
1646
[email protected]23e482282013-06-14 16:08:021647void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511648 const MockWrite* write_failure,
1649 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421650 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521651 request.method = "GET";
1652 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101653 request.traffic_annotation =
1654 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521655
vishal.b62985ca92015-04-17 08:45:511656 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071657 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091658 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271659
[email protected]202965992011-12-07 23:04:511660 // Written data for successfully sending both requests.
1661 MockWrite data1_writes[] = {
1662 MockWrite("GET / HTTP/1.1\r\n"
1663 "Host: www.foo.com\r\n"
1664 "Connection: keep-alive\r\n\r\n"),
1665 MockWrite("GET / HTTP/1.1\r\n"
1666 "Host: www.foo.com\r\n"
1667 "Connection: keep-alive\r\n\r\n")
1668 };
1669
1670 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521671 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351672 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1673 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061674 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521675 };
[email protected]202965992011-12-07 23:04:511676
1677 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491678 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511679 data1_writes[1] = *write_failure;
1680 } else {
1681 ASSERT_TRUE(read_failure);
1682 data1_reads[2] = *read_failure;
1683 }
1684
Ryan Sleevib8d7ea02018-05-07 20:01:011685 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]bb88e1d32013-05-03 23:11:071686 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521687
1688 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351689 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1690 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061691 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521692 };
Ryan Sleevib8d7ea02018-05-07 20:01:011693 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071694 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521695
thestig9d3bb0c2015-01-24 00:49:511696 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521697 "hello", "world"
1698 };
1699
mikecironef22f9812016-10-04 03:40:191700 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521701 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411702 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521703
bnc691fda62016-08-12 00:43:161704 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521705
tfarina42834112016-09-22 13:38:201706 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011707 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521708
1709 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011710 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521711
[email protected]58e32bb2013-01-21 18:23:251712 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161713 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251714 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1715 if (i == 0) {
1716 first_socket_log_id = load_timing_info.socket_log_id;
1717 } else {
1718 // The second request should be using a new socket.
1719 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1720 }
1721
bnc691fda62016-08-12 00:43:161722 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521723 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521724
wezca1070932016-05-26 20:30:521725 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471726 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251727 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521728
1729 std::string response_data;
bnc691fda62016-08-12 00:43:161730 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011731 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251732 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521733 }
1734}
[email protected]3d2a59b2008-09-26 19:44:251735
[email protected]a34f61ee2014-03-18 20:59:491736void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1737 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101738 const MockRead* read_failure,
1739 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491740 HttpRequestInfo request;
1741 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101742 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101743 request.traffic_annotation =
1744 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491745
vishal.b62985ca92015-04-17 08:45:511746 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491747 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091748 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491749
[email protected]09356c652014-03-25 15:36:101750 SSLSocketDataProvider ssl1(ASYNC, OK);
1751 SSLSocketDataProvider ssl2(ASYNC, OK);
1752 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361753 ssl1.next_proto = kProtoHTTP2;
1754 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101755 }
1756 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1757 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491758
[email protected]09356c652014-03-25 15:36:101759 // SPDY versions of the request and response.
Ryan Hamilton0239aac2018-05-19 00:03:131760 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491761 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131762 spdy::SpdySerializedFrame spdy_response(
Raul Tambre94493c652019-03-11 17:18:351763 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131764 spdy::SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191765 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491766
[email protected]09356c652014-03-25 15:36:101767 // HTTP/1.1 versions of the request and response.
1768 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1769 "Host: www.foo.com\r\n"
1770 "Connection: keep-alive\r\n\r\n";
1771 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1772 const char kHttpData[] = "hello";
1773
1774 std::vector<MockRead> data1_reads;
1775 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491776 if (write_failure) {
1777 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101778 data1_writes.push_back(*write_failure);
1779 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491780 } else {
1781 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101782 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411783 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101784 } else {
1785 data1_writes.push_back(MockWrite(kHttpRequest));
1786 }
1787 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491788 }
1789
Ryan Sleevib8d7ea02018-05-07 20:01:011790 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]a34f61ee2014-03-18 20:59:491791 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1792
[email protected]09356c652014-03-25 15:36:101793 std::vector<MockRead> data2_reads;
1794 std::vector<MockWrite> data2_writes;
1795
1796 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411797 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101798
bncdf80d44fd2016-07-15 20:27:411799 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1800 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101801 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1802 } else {
1803 data2_writes.push_back(
1804 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1805
1806 data2_reads.push_back(
1807 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1808 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1809 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1810 }
Ryan Sleevib8d7ea02018-05-07 20:01:011811 SequencedSocketData data2(data2_reads, data2_writes);
[email protected]a34f61ee2014-03-18 20:59:491812 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1813
1814 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591815 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491816 // Wait for the preconnect to complete.
1817 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1818 base::RunLoop().RunUntilIdle();
Matt Menke9d5e2c92019-02-05 01:42:231819 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491820
1821 // Make the request.
1822 TestCompletionCallback callback;
1823
bnc691fda62016-08-12 00:43:161824 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491825
tfarina42834112016-09-22 13:38:201826 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011827 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491828
1829 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011830 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491831
1832 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161833 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101834 TestLoadTimingNotReused(
1835 load_timing_info,
1836 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491837
bnc691fda62016-08-12 00:43:161838 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521839 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491840
wezca1070932016-05-26 20:30:521841 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021842 if (response->was_fetched_via_spdy) {
1843 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1844 } else {
1845 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1846 }
[email protected]a34f61ee2014-03-18 20:59:491847
1848 std::string response_data;
bnc691fda62016-08-12 00:43:161849 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011850 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101851 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491852}
1853
Biljith Jayan45a41722017-08-16 18:43:141854// Test that we do not retry indefinitely when a server sends an error like
1855// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1856// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1857TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1858 HttpRequestInfo request;
1859 request.method = "GET";
1860 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101861 request.traffic_annotation =
1862 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141863
1864 // Check whether we give up after the third try.
1865
1866 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131867 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141868 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131869 spdy::SpdySerializedFrame spdy_response_go_away(
1870 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011871 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1872 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141873
1874 // Three go away responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011875 StaticSocketDataProvider data1(data_read1, data_write);
1876 StaticSocketDataProvider data2(data_read1, data_write);
1877 StaticSocketDataProvider data3(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141878
1879 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1880 AddSSLSocketData();
1881 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1882 AddSSLSocketData();
1883 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1884 AddSSLSocketData();
1885
1886 TestCompletionCallback callback;
1887 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1888 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1889
1890 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1892
1893 rv = callback.WaitForResult();
1894 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1895}
1896
1897TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1898 HttpRequestInfo request;
1899 request.method = "GET";
1900 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101901 request.traffic_annotation =
1902 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141903
1904 // Check whether we try atleast thrice before giving up.
1905
1906 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131907 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141908 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131909 spdy::SpdySerializedFrame spdy_response_go_away(
1910 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011911 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1912 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141913
1914 // Construct a non error HTTP2 response.
Ryan Hamilton0239aac2018-05-19 00:03:131915 spdy::SpdySerializedFrame spdy_response_no_error(
Biljith Jayan45a41722017-08-16 18:43:141916 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131917 spdy::SpdySerializedFrame spdy_data(
1918 spdy_util_.ConstructSpdyDataFrame(1, true));
Biljith Jayan45a41722017-08-16 18:43:141919 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1920 CreateMockRead(spdy_data, 2)};
1921
1922 // Two error responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011923 StaticSocketDataProvider data1(data_read1, data_write);
1924 StaticSocketDataProvider data2(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141925 // Followed by a success response.
Ryan Sleevib8d7ea02018-05-07 20:01:011926 SequencedSocketData data3(data_read2, data_write);
Biljith Jayan45a41722017-08-16 18:43:141927
1928 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1929 AddSSLSocketData();
1930 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1931 AddSSLSocketData();
1932 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1933 AddSSLSocketData();
1934
1935 TestCompletionCallback callback;
1936 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1937 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1938
1939 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1941
1942 rv = callback.WaitForResult();
1943 EXPECT_THAT(rv, IsOk());
1944}
1945
bncd16676a2016-07-20 16:23:011946TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061947 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:351948 KeepAliveConnectionResendRequestTest(&write_failure, nullptr);
[email protected]202965992011-12-07 23:04:511949}
1950
bncd16676a2016-07-20 16:23:011951TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061952 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:351953 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251954}
1955
bncd16676a2016-07-20 16:23:011956TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061957 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351958 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251959}
1960
[email protected]d58ceea82014-06-04 10:55:541961// Make sure that on a 408 response (Request Timeout), the request is retried,
1962// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011963TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541964 MockRead read_failure(SYNCHRONOUS,
1965 "HTTP/1.1 408 Request Timeout\r\n"
1966 "Connection: Keep-Alive\r\n"
1967 "Content-Length: 6\r\n\r\n"
1968 "Pickle");
Raul Tambre94493c652019-03-11 17:18:351969 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]d58ceea82014-06-04 10:55:541970}
1971
bncd16676a2016-07-20 16:23:011972TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491973 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:351974 PreconnectErrorResendRequestTest(&write_failure, nullptr, false);
[email protected]a34f61ee2014-03-18 20:59:491975}
1976
bncd16676a2016-07-20 16:23:011977TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491978 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:351979 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491980}
1981
bncd16676a2016-07-20 16:23:011982TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491983 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351984 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]09356c652014-03-25 15:36:101985}
1986
bncd16676a2016-07-20 16:23:011987TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101988 MockRead read_failure(ASYNC, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351989 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]09356c652014-03-25 15:36:101990}
1991
[email protected]d58ceea82014-06-04 10:55:541992// Make sure that on a 408 response (Request Timeout), the request is retried,
1993// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011994TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541995 MockRead read_failure(SYNCHRONOUS,
1996 "HTTP/1.1 408 Request Timeout\r\n"
1997 "Connection: Keep-Alive\r\n"
1998 "Content-Length: 6\r\n\r\n"
1999 "Pickle");
Raul Tambre94493c652019-03-11 17:18:352000 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
2001 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]d58ceea82014-06-04 10:55:542002}
2003
bncd16676a2016-07-20 16:23:012004TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:102005 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:352006 PreconnectErrorResendRequestTest(&write_failure, nullptr, true);
[email protected]09356c652014-03-25 15:36:102007}
2008
bncd16676a2016-07-20 16:23:012009TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:102010 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:352011 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]09356c652014-03-25 15:36:102012}
2013
bncd16676a2016-07-20 16:23:012014TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:102015 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352016 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]09356c652014-03-25 15:36:102017}
2018
bncd16676a2016-07-20 16:23:012019TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:102020 MockRead read_failure(ASYNC, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352021 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:492022}
2023
bncd16676a2016-07-20 16:23:012024TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:422025 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:252026 request.method = "GET";
bncce36dca22015-04-21 22:11:232027 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102028 request.traffic_annotation =
2029 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:252030
danakj1fd259a02016-04-16 03:17:092031 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162032 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272033
[email protected]3d2a59b2008-09-26 19:44:252034 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062035 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:352036 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2037 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062038 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252039 };
Ryan Sleevib8d7ea02018-05-07 20:01:012040 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072041 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:252042
[email protected]49639fa2011-12-20 23:22:412043 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:252044
tfarina42834112016-09-22 13:38:202045 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012046 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:252047
2048 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012049 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:592050
2051 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162052 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592053 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:252054}
2055
2056// What do various browsers do when the server closes a non-keepalive
2057// connection without sending any response header or body?
2058//
2059// IE7: error page
2060// Safari 3.1.2 (Windows): error page
2061// Firefox 3.0.1: blank page
2062// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:422063// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
2064// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:012065TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:252066 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062067 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:352068 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2069 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062070 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252071 };
Ryan Sleevib8d7ea02018-05-07 20:01:012072 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:012073 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:252074}
[email protected]1826a402014-01-08 15:40:482075
[email protected]7a5378b2012-11-04 03:25:172076// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
2077// tests. There was a bug causing HttpNetworkTransaction to hang in the
2078// destructor in such situations.
2079// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:012080TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:172081 HttpRequestInfo request;
2082 request.method = "GET";
bncce36dca22015-04-21 22:11:232083 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102084 request.traffic_annotation =
2085 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172086
danakj1fd259a02016-04-16 03:17:092087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582088 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192089 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172090
2091 MockRead data_reads[] = {
2092 MockRead("HTTP/1.0 200 OK\r\n"),
2093 MockRead("Connection: keep-alive\r\n"),
2094 MockRead("Content-Length: 100\r\n\r\n"),
2095 MockRead("hello"),
2096 MockRead(SYNCHRONOUS, 0),
2097 };
Ryan Sleevib8d7ea02018-05-07 20:01:012098 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072099 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172100
2101 TestCompletionCallback callback;
2102
tfarina42834112016-09-22 13:38:202103 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012104 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172105
2106 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012107 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172108
Victor Costan9c7302b2018-08-27 16:39:442109 scoped_refptr<IOBufferWithSize> io_buf =
2110 base::MakeRefCounted<IOBufferWithSize>(100);
[email protected]90499482013-06-01 00:39:502111 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172112 if (rv == ERR_IO_PENDING)
2113 rv = callback.WaitForResult();
2114 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:502115 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:012116 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172117
2118 trans.reset();
fdoray92e35a72016-06-10 15:54:552119 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172120 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2121}
2122
bncd16676a2016-07-20 16:23:012123TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:172124 HttpRequestInfo request;
2125 request.method = "GET";
bncce36dca22015-04-21 22:11:232126 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102127 request.traffic_annotation =
2128 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172129
danakj1fd259a02016-04-16 03:17:092130 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582131 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192132 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172133
2134 MockRead data_reads[] = {
2135 MockRead("HTTP/1.0 200 OK\r\n"),
2136 MockRead("Connection: keep-alive\r\n"),
2137 MockRead("Content-Length: 100\r\n\r\n"),
2138 MockRead(SYNCHRONOUS, 0),
2139 };
Ryan Sleevib8d7ea02018-05-07 20:01:012140 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072141 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172142
2143 TestCompletionCallback callback;
2144
tfarina42834112016-09-22 13:38:202145 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012146 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172147
2148 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012149 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172150
Victor Costan9c7302b2018-08-27 16:39:442151 scoped_refptr<IOBufferWithSize> io_buf(
2152 base::MakeRefCounted<IOBufferWithSize>(100));
[email protected]90499482013-06-01 00:39:502153 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172154 if (rv == ERR_IO_PENDING)
2155 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012156 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172157
2158 trans.reset();
fdoray92e35a72016-06-10 15:54:552159 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172160 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2161}
2162
[email protected]0b0bf032010-09-21 18:08:502163// Test that we correctly reuse a keep-alive connection after not explicitly
2164// reading the body.
bncd16676a2016-07-20 16:23:012165TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132166 HttpRequestInfo request;
2167 request.method = "GET";
2168 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102169 request.traffic_annotation =
2170 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132171
vishal.b62985ca92015-04-17 08:45:512172 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072173 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092174 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272175
mmenkecc2298e2015-12-07 18:20:182176 const char* request_data =
2177 "GET / HTTP/1.1\r\n"
2178 "Host: www.foo.com\r\n"
2179 "Connection: keep-alive\r\n\r\n";
2180 MockWrite data_writes[] = {
2181 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2182 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2183 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2184 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2185 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2186 };
2187
[email protected]0b0bf032010-09-21 18:08:502188 // Note that because all these reads happen in the same
2189 // StaticSocketDataProvider, it shows that the same socket is being reused for
2190 // all transactions.
mmenkecc2298e2015-12-07 18:20:182191 MockRead data_reads[] = {
2192 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2193 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2194 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2195 MockRead(ASYNC, 7,
2196 "HTTP/1.1 302 Found\r\n"
2197 "Content-Length: 0\r\n\r\n"),
2198 MockRead(ASYNC, 9,
2199 "HTTP/1.1 302 Found\r\n"
2200 "Content-Length: 5\r\n\r\n"
2201 "hello"),
2202 MockRead(ASYNC, 11,
2203 "HTTP/1.1 301 Moved Permanently\r\n"
2204 "Content-Length: 0\r\n\r\n"),
2205 MockRead(ASYNC, 13,
2206 "HTTP/1.1 301 Moved Permanently\r\n"
2207 "Content-Length: 5\r\n\r\n"
2208 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132209
mmenkecc2298e2015-12-07 18:20:182210 // In the next two rounds, IsConnectedAndIdle returns false, due to
2211 // the set_busy_before_sync_reads(true) call, while the
2212 // HttpNetworkTransaction is being shut down, but the socket is still
2213 // reuseable. See http://crbug.com/544255.
2214 MockRead(ASYNC, 15,
2215 "HTTP/1.1 200 Hunky-Dory\r\n"
2216 "Content-Length: 5\r\n\r\n"),
2217 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132218
mmenkecc2298e2015-12-07 18:20:182219 MockRead(ASYNC, 18,
2220 "HTTP/1.1 200 Hunky-Dory\r\n"
2221 "Content-Length: 5\r\n\r\n"
2222 "he"),
2223 MockRead(SYNCHRONOUS, 19, "llo"),
2224
2225 // The body of the final request is actually read.
2226 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2227 MockRead(ASYNC, 22, "hello"),
2228 };
Ryan Sleevib8d7ea02018-05-07 20:01:012229 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182230 data.set_busy_before_sync_reads(true);
2231 session_deps_.socket_factory->AddSocketDataProvider(&data);
2232
Avi Drissman4365a4782018-12-28 19:26:242233 const int kNumUnreadBodies = base::size(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502234 std::string response_lines[kNumUnreadBodies];
2235
mikecironef22f9812016-10-04 03:40:192236 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182237 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412238 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132239
Jeremy Roman0579ed62017-08-29 15:56:192240 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582241 session.get());
[email protected]fc31d6a42010-06-24 18:05:132242
tfarina42834112016-09-22 13:38:202243 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012244 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132245
[email protected]58e32bb2013-01-21 18:23:252246 LoadTimingInfo load_timing_info;
2247 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2248 if (i == 0) {
2249 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2250 first_socket_log_id = load_timing_info.socket_log_id;
2251 } else {
2252 TestLoadTimingReused(load_timing_info);
2253 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2254 }
2255
[email protected]fc31d6a42010-06-24 18:05:132256 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182257 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132258
mmenkecc2298e2015-12-07 18:20:182259 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502260 response_lines[i] = response->headers->GetStatusLine();
2261
mmenkecc2298e2015-12-07 18:20:182262 // Delete the transaction without reading the response bodies. Then spin
2263 // the message loop, so the response bodies are drained.
2264 trans.reset();
2265 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132266 }
[email protected]0b0bf032010-09-21 18:08:502267
2268 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182269 "HTTP/1.1 204 No Content",
2270 "HTTP/1.1 205 Reset Content",
2271 "HTTP/1.1 304 Not Modified",
2272 "HTTP/1.1 302 Found",
2273 "HTTP/1.1 302 Found",
2274 "HTTP/1.1 301 Moved Permanently",
2275 "HTTP/1.1 301 Moved Permanently",
2276 "HTTP/1.1 200 Hunky-Dory",
2277 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502278 };
2279
Avi Drissman4365a4782018-12-28 19:26:242280 static_assert(kNumUnreadBodies == base::size(kStatusLines),
mostynb91e0da982015-01-20 19:17:272281 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502282
2283 for (int i = 0; i < kNumUnreadBodies; ++i)
2284 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2285
[email protected]49639fa2011-12-20 23:22:412286 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162287 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202288 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012289 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162290 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182291 ASSERT_TRUE(response);
2292 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502293 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2294 std::string response_data;
bnc691fda62016-08-12 00:43:162295 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012296 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502297 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132298}
2299
mmenke5f94fda2016-06-02 20:54:132300// Sockets that receive extra data after a response is complete should not be
2301// reused.
bncd16676a2016-07-20 16:23:012302TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132303 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2304 MockWrite data_writes1[] = {
2305 MockWrite("HEAD / HTTP/1.1\r\n"
2306 "Host: www.borked.com\r\n"
2307 "Connection: keep-alive\r\n\r\n"),
2308 };
2309
2310 MockRead data_reads1[] = {
2311 MockRead("HTTP/1.1 200 OK\r\n"
2312 "Connection: keep-alive\r\n"
2313 "Content-Length: 22\r\n\r\n"
2314 "This server is borked."),
2315 };
2316
2317 MockWrite data_writes2[] = {
2318 MockWrite("GET /foo 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_reads2[] = {
2324 MockRead("HTTP/1.1 200 OK\r\n"
2325 "Content-Length: 3\r\n\r\n"
2326 "foo"),
2327 };
Ryan Sleevib8d7ea02018-05-07 20:01:012328 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132329 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012330 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132331 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2332
2333 TestCompletionCallback callback;
2334 HttpRequestInfo request1;
2335 request1.method = "HEAD";
2336 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102337 request1.traffic_annotation =
2338 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132339
bnc87dcefc2017-05-25 12:47:582340 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192341 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202342 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012343 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132344
2345 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2346 ASSERT_TRUE(response1);
2347 ASSERT_TRUE(response1->headers);
2348 EXPECT_EQ(200, response1->headers->response_code());
2349 EXPECT_TRUE(response1->headers->IsKeepAlive());
2350
2351 std::string response_data1;
robpercival214763f2016-07-01 23:27:012352 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132353 EXPECT_EQ("", response_data1);
2354 // Deleting the transaction attempts to release the socket back into the
2355 // socket pool.
2356 trans1.reset();
2357
2358 HttpRequestInfo request2;
2359 request2.method = "GET";
2360 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102361 request2.traffic_annotation =
2362 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132363
bnc87dcefc2017-05-25 12:47:582364 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192365 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202366 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012367 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132368
2369 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2370 ASSERT_TRUE(response2);
2371 ASSERT_TRUE(response2->headers);
2372 EXPECT_EQ(200, response2->headers->response_code());
2373
2374 std::string response_data2;
robpercival214763f2016-07-01 23:27:012375 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132376 EXPECT_EQ("foo", response_data2);
2377}
2378
bncd16676a2016-07-20 16:23:012379TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132380 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2381 MockWrite data_writes1[] = {
2382 MockWrite("GET / HTTP/1.1\r\n"
2383 "Host: www.borked.com\r\n"
2384 "Connection: keep-alive\r\n\r\n"),
2385 };
2386
2387 MockRead data_reads1[] = {
2388 MockRead("HTTP/1.1 200 OK\r\n"
2389 "Connection: keep-alive\r\n"
2390 "Content-Length: 22\r\n\r\n"
2391 "This server is borked."
2392 "Bonus data!"),
2393 };
2394
2395 MockWrite data_writes2[] = {
2396 MockWrite("GET /foo HTTP/1.1\r\n"
2397 "Host: www.borked.com\r\n"
2398 "Connection: keep-alive\r\n\r\n"),
2399 };
2400
2401 MockRead data_reads2[] = {
2402 MockRead("HTTP/1.1 200 OK\r\n"
2403 "Content-Length: 3\r\n\r\n"
2404 "foo"),
2405 };
Ryan Sleevib8d7ea02018-05-07 20:01:012406 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132407 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012408 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132409 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2410
2411 TestCompletionCallback callback;
2412 HttpRequestInfo request1;
2413 request1.method = "GET";
2414 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102415 request1.traffic_annotation =
2416 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132417
bnc87dcefc2017-05-25 12:47:582418 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192419 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202420 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012421 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132422
2423 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2424 ASSERT_TRUE(response1);
2425 ASSERT_TRUE(response1->headers);
2426 EXPECT_EQ(200, response1->headers->response_code());
2427 EXPECT_TRUE(response1->headers->IsKeepAlive());
2428
2429 std::string response_data1;
robpercival214763f2016-07-01 23:27:012430 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132431 EXPECT_EQ("This server is borked.", response_data1);
2432 // Deleting the transaction attempts to release the socket back into the
2433 // socket pool.
2434 trans1.reset();
2435
2436 HttpRequestInfo request2;
2437 request2.method = "GET";
2438 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102439 request2.traffic_annotation =
2440 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132441
bnc87dcefc2017-05-25 12:47:582442 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192443 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202444 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012445 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132446
2447 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2448 ASSERT_TRUE(response2);
2449 ASSERT_TRUE(response2->headers);
2450 EXPECT_EQ(200, response2->headers->response_code());
2451
2452 std::string response_data2;
robpercival214763f2016-07-01 23:27:012453 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132454 EXPECT_EQ("foo", response_data2);
2455}
2456
bncd16676a2016-07-20 16:23:012457TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132458 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2459 MockWrite data_writes1[] = {
2460 MockWrite("GET / HTTP/1.1\r\n"
2461 "Host: www.borked.com\r\n"
2462 "Connection: keep-alive\r\n\r\n"),
2463 };
2464
2465 MockRead data_reads1[] = {
2466 MockRead("HTTP/1.1 200 OK\r\n"
2467 "Connection: keep-alive\r\n"
2468 "Transfer-Encoding: chunked\r\n\r\n"),
2469 MockRead("16\r\nThis server is borked.\r\n"),
2470 MockRead("0\r\n\r\nBonus data!"),
2471 };
2472
2473 MockWrite data_writes2[] = {
2474 MockWrite("GET /foo HTTP/1.1\r\n"
2475 "Host: www.borked.com\r\n"
2476 "Connection: keep-alive\r\n\r\n"),
2477 };
2478
2479 MockRead data_reads2[] = {
2480 MockRead("HTTP/1.1 200 OK\r\n"
2481 "Content-Length: 3\r\n\r\n"
2482 "foo"),
2483 };
Ryan Sleevib8d7ea02018-05-07 20:01:012484 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132485 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012486 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132487 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2488
2489 TestCompletionCallback callback;
2490 HttpRequestInfo request1;
2491 request1.method = "GET";
2492 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102493 request1.traffic_annotation =
2494 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132495
bnc87dcefc2017-05-25 12:47:582496 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192497 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202498 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012499 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132500
2501 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2502 ASSERT_TRUE(response1);
2503 ASSERT_TRUE(response1->headers);
2504 EXPECT_EQ(200, response1->headers->response_code());
2505 EXPECT_TRUE(response1->headers->IsKeepAlive());
2506
2507 std::string response_data1;
robpercival214763f2016-07-01 23:27:012508 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132509 EXPECT_EQ("This server is borked.", response_data1);
2510 // Deleting the transaction attempts to release the socket back into the
2511 // socket pool.
2512 trans1.reset();
2513
2514 HttpRequestInfo request2;
2515 request2.method = "GET";
2516 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102517 request2.traffic_annotation =
2518 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132519
bnc87dcefc2017-05-25 12:47:582520 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192521 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202522 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012523 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132524
2525 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2526 ASSERT_TRUE(response2);
2527 ASSERT_TRUE(response2->headers);
2528 EXPECT_EQ(200, response2->headers->response_code());
2529
2530 std::string response_data2;
robpercival214763f2016-07-01 23:27:012531 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132532 EXPECT_EQ("foo", response_data2);
2533}
2534
2535// This is a little different from the others - it tests the case that the
2536// HttpStreamParser doesn't know if there's extra data on a socket or not when
2537// the HttpNetworkTransaction is torn down, because the response body hasn't
2538// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012539TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132540 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2541 MockWrite data_writes1[] = {
2542 MockWrite("GET / HTTP/1.1\r\n"
2543 "Host: www.borked.com\r\n"
2544 "Connection: keep-alive\r\n\r\n"),
2545 };
2546
2547 MockRead data_reads1[] = {
2548 MockRead("HTTP/1.1 200 OK\r\n"
2549 "Connection: keep-alive\r\n"
2550 "Transfer-Encoding: chunked\r\n\r\n"),
2551 MockRead("16\r\nThis server is borked.\r\n"),
2552 MockRead("0\r\n\r\nBonus data!"),
2553 };
Ryan Sleevib8d7ea02018-05-07 20:01:012554 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132555 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2556
2557 TestCompletionCallback callback;
2558 HttpRequestInfo request1;
2559 request1.method = "GET";
2560 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102561 request1.traffic_annotation =
2562 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132563
bnc87dcefc2017-05-25 12:47:582564 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192565 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582566 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012567 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132568
bnc87dcefc2017-05-25 12:47:582569 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132570 ASSERT_TRUE(response1);
2571 ASSERT_TRUE(response1->headers);
2572 EXPECT_EQ(200, response1->headers->response_code());
2573 EXPECT_TRUE(response1->headers->IsKeepAlive());
2574
2575 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2576 // response body.
bnc87dcefc2017-05-25 12:47:582577 trans.reset();
mmenke5f94fda2016-06-02 20:54:132578
2579 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2580 // socket can't be reused, rather than returning it to the socket pool.
2581 base::RunLoop().RunUntilIdle();
2582
2583 // There should be no idle sockets in the pool.
2584 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2585}
2586
[email protected]038e9a32008-10-08 22:40:162587// Test the request-challenge-retry sequence for basic auth.
2588// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012589TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422590 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162591 request.method = "GET";
bncce36dca22015-04-21 22:11:232592 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102593 request.traffic_annotation =
2594 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162595
vishal.b62985ca92015-04-17 08:45:512596 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072597 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092598 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162599 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272600
[email protected]f9ee6b52008-11-08 06:46:232601 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232602 MockWrite(
2603 "GET / HTTP/1.1\r\n"
2604 "Host: www.example.org\r\n"
2605 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232606 };
2607
[email protected]038e9a32008-10-08 22:40:162608 MockRead data_reads1[] = {
2609 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2610 // Give a couple authenticate options (only the middle one is actually
2611 // supported).
[email protected]22927ad2009-09-21 19:56:192612 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162613 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2614 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2615 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2616 // Large content-length -- won't matter, as connection will be reset.
2617 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062618 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162619 };
2620
2621 // After calling trans->RestartWithAuth(), this is the request we should
2622 // be issuing -- the final header line contains the credentials.
2623 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232624 MockWrite(
2625 "GET / HTTP/1.1\r\n"
2626 "Host: www.example.org\r\n"
2627 "Connection: keep-alive\r\n"
2628 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162629 };
2630
2631 // Lastly, the server responds with the actual content.
2632 MockRead data_reads2[] = {
2633 MockRead("HTTP/1.0 200 OK\r\n"),
2634 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2635 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062636 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162637 };
2638
Ryan Sleevib8d7ea02018-05-07 20:01:012639 StaticSocketDataProvider data1(data_reads1, data_writes1);
2640 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072641 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2642 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162643
[email protected]49639fa2011-12-20 23:22:412644 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162645
tfarina42834112016-09-22 13:38:202646 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162648
2649 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012650 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162651
[email protected]58e32bb2013-01-21 18:23:252652 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162653 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252654 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2655
Ryan Sleevib8d7ea02018-05-07 20:01:012656 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162657 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012658 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162659 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192660
bnc691fda62016-08-12 00:43:162661 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522662 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042663 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162664
[email protected]49639fa2011-12-20 23:22:412665 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162666
bnc691fda62016-08-12 00:43:162667 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012668 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162669
2670 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012671 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162672
[email protected]58e32bb2013-01-21 18:23:252673 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162674 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252675 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2676 // The load timing after restart should have a new socket ID, and times after
2677 // those of the first load timing.
2678 EXPECT_LE(load_timing_info1.receive_headers_end,
2679 load_timing_info2.connect_timing.connect_start);
2680 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2681
Ryan Sleevib8d7ea02018-05-07 20:01:012682 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162683 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012684 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162685 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192686
bnc691fda62016-08-12 00:43:162687 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522688 ASSERT_TRUE(response);
2689 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162690 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162691}
2692
ttuttled9dbc652015-09-29 20:00:592693// Test the request-challenge-retry sequence for basic auth.
2694// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012695TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592696 HttpRequestInfo request;
2697 request.method = "GET";
2698 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102699 request.traffic_annotation =
2700 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592701
2702 TestNetLog log;
2703 MockHostResolver* resolver = new MockHostResolver();
2704 session_deps_.net_log = &log;
2705 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092706 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162707 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592708
2709 resolver->rules()->ClearRules();
2710 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2711
2712 MockWrite data_writes1[] = {
2713 MockWrite("GET / HTTP/1.1\r\n"
2714 "Host: www.example.org\r\n"
2715 "Connection: keep-alive\r\n\r\n"),
2716 };
2717
2718 MockRead data_reads1[] = {
2719 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2720 // Give a couple authenticate options (only the middle one is actually
2721 // supported).
2722 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2723 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2724 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2725 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2726 // Large content-length -- won't matter, as connection will be reset.
2727 MockRead("Content-Length: 10000\r\n\r\n"),
2728 MockRead(SYNCHRONOUS, ERR_FAILED),
2729 };
2730
2731 // After calling trans->RestartWithAuth(), this is the request we should
2732 // be issuing -- the final header line contains the credentials.
2733 MockWrite data_writes2[] = {
2734 MockWrite("GET / HTTP/1.1\r\n"
2735 "Host: www.example.org\r\n"
2736 "Connection: keep-alive\r\n"
2737 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2738 };
2739
2740 // Lastly, the server responds with the actual content.
2741 MockRead data_reads2[] = {
2742 MockRead("HTTP/1.0 200 OK\r\n"),
2743 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2744 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2745 };
2746
Ryan Sleevib8d7ea02018-05-07 20:01:012747 StaticSocketDataProvider data1(data_reads1, data_writes1);
2748 StaticSocketDataProvider data2(data_reads2, data_writes2);
ttuttled9dbc652015-09-29 20:00:592749 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2750 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2751
2752 TestCompletionCallback callback1;
2753
bnc691fda62016-08-12 00:43:162754 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202755 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592756
2757 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162758 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592759 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2760
Ryan Sleevib8d7ea02018-05-07 20:01:012761 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162762 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012763 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162764 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592765
bnc691fda62016-08-12 00:43:162766 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592767 ASSERT_TRUE(response);
2768 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2769
2770 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162771 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592772 ASSERT_FALSE(endpoint.address().empty());
2773 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2774
2775 resolver->rules()->ClearRules();
2776 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2777
2778 TestCompletionCallback callback2;
2779
bnc691fda62016-08-12 00:43:162780 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592781 AuthCredentials(kFoo, kBar), callback2.callback())));
2782
2783 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162784 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592785 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2786 // The load timing after restart should have a new socket ID, and times after
2787 // those of the first load timing.
2788 EXPECT_LE(load_timing_info1.receive_headers_end,
2789 load_timing_info2.connect_timing.connect_start);
2790 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2791
Ryan Sleevib8d7ea02018-05-07 20:01:012792 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162793 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012794 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162795 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592796
bnc691fda62016-08-12 00:43:162797 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592798 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522799 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592800 EXPECT_EQ(100, response->headers->GetContentLength());
2801
bnc691fda62016-08-12 00:43:162802 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592803 ASSERT_FALSE(endpoint.address().empty());
2804 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2805}
2806
David Benjamin83ddfb32018-03-30 01:07:522807// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2808// will eventually give up.
2809TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2810 HttpRequestInfo request;
2811 request.method = "GET";
2812 request.url = GURL("http://www.example.org/");
2813 request.traffic_annotation =
2814 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2815
2816 TestNetLog log;
2817 session_deps_.net_log = &log;
2818 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2819 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2820
2821 MockWrite data_writes[] = {
2822 MockWrite("GET / HTTP/1.1\r\n"
2823 "Host: www.example.org\r\n"
2824 "Connection: keep-alive\r\n\r\n"),
2825 };
2826
2827 MockRead data_reads[] = {
2828 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2829 // Give a couple authenticate options (only the middle one is actually
2830 // supported).
2831 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2832 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2833 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2834 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2835 // Large content-length -- won't matter, as connection will be reset.
2836 MockRead("Content-Length: 10000\r\n\r\n"),
2837 MockRead(SYNCHRONOUS, ERR_FAILED),
2838 };
2839
2840 // After calling trans->RestartWithAuth(), this is the request we should
2841 // be issuing -- the final header line contains the credentials.
2842 MockWrite data_writes_restart[] = {
2843 MockWrite("GET / HTTP/1.1\r\n"
2844 "Host: www.example.org\r\n"
2845 "Connection: keep-alive\r\n"
2846 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2847 };
2848
Ryan Sleevib8d7ea02018-05-07 20:01:012849 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin83ddfb32018-03-30 01:07:522850 session_deps_.socket_factory->AddSocketDataProvider(&data);
2851
2852 TestCompletionCallback callback;
2853 int rv = callback.GetResult(
2854 trans.Start(&request, callback.callback(), NetLogWithSource()));
2855
2856 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2857 for (int i = 0; i < 32; i++) {
2858 // Check the previous response was a 401.
2859 EXPECT_THAT(rv, IsOk());
2860 const HttpResponseInfo* response = trans.GetResponseInfo();
2861 ASSERT_TRUE(response);
2862 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2863
2864 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:012865 data_reads, data_writes_restart));
David Benjamin83ddfb32018-03-30 01:07:522866 session_deps_.socket_factory->AddSocketDataProvider(
2867 data_restarts.back().get());
2868 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2869 callback.callback()));
2870 }
2871
2872 // After too many tries, the transaction should have given up.
2873 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2874}
2875
bncd16676a2016-07-20 16:23:012876TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462877 HttpRequestInfo request;
2878 request.method = "GET";
bncce36dca22015-04-21 22:11:232879 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292880 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:102881 request.traffic_annotation =
2882 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462883
danakj1fd259a02016-04-16 03:17:092884 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162885 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272886
[email protected]861fcd52009-08-26 02:33:462887 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232888 MockWrite(
2889 "GET / HTTP/1.1\r\n"
2890 "Host: www.example.org\r\n"
2891 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462892 };
2893
2894 MockRead data_reads[] = {
2895 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2896 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2897 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2898 // Large content-length -- won't matter, as connection will be reset.
2899 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062900 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462901 };
2902
Ryan Sleevib8d7ea02018-05-07 20:01:012903 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:072904 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412905 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462906
tfarina42834112016-09-22 13:38:202907 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012908 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462909
2910 rv = callback.WaitForResult();
2911 EXPECT_EQ(0, rv);
2912
Ryan Sleevib8d7ea02018-05-07 20:01:012913 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162914 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012915 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162916 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192917
bnc691fda62016-08-12 00:43:162918 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522919 ASSERT_TRUE(response);
2920 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462921}
2922
[email protected]2d2697f92009-02-18 21:00:322923// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2924// connection.
bncd16676a2016-07-20 16:23:012925TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182926 // On the second pass, the body read of the auth challenge is synchronous, so
2927 // IsConnectedAndIdle returns false. The socket should still be drained and
2928 // reused. See http://crbug.com/544255.
2929 for (int i = 0; i < 2; ++i) {
2930 HttpRequestInfo request;
2931 request.method = "GET";
2932 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102933 request.traffic_annotation =
2934 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322935
mmenkecc2298e2015-12-07 18:20:182936 TestNetLog log;
2937 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092938 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272939
mmenkecc2298e2015-12-07 18:20:182940 MockWrite data_writes[] = {
2941 MockWrite(ASYNC, 0,
2942 "GET / HTTP/1.1\r\n"
2943 "Host: www.example.org\r\n"
2944 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322945
bnc691fda62016-08-12 00:43:162946 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182947 // be issuing -- the final header line contains the credentials.
2948 MockWrite(ASYNC, 6,
2949 "GET / HTTP/1.1\r\n"
2950 "Host: www.example.org\r\n"
2951 "Connection: keep-alive\r\n"
2952 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2953 };
[email protected]2d2697f92009-02-18 21:00:322954
mmenkecc2298e2015-12-07 18:20:182955 MockRead data_reads[] = {
2956 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2957 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2958 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2959 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2960 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322961
mmenkecc2298e2015-12-07 18:20:182962 // Lastly, the server responds with the actual content.
2963 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2964 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2965 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2966 MockRead(ASYNC, 10, "Hello"),
2967 };
[email protected]2d2697f92009-02-18 21:00:322968
Ryan Sleevib8d7ea02018-05-07 20:01:012969 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182970 data.set_busy_before_sync_reads(true);
2971 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462972
mmenkecc2298e2015-12-07 18:20:182973 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322974
bnc691fda62016-08-12 00:43:162975 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202976 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012977 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322978
mmenkecc2298e2015-12-07 18:20:182979 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162980 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182981 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322982
bnc691fda62016-08-12 00:43:162983 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182984 ASSERT_TRUE(response);
2985 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322986
mmenkecc2298e2015-12-07 18:20:182987 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252988
bnc691fda62016-08-12 00:43:162989 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2990 callback2.callback());
robpercival214763f2016-07-01 23:27:012991 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322992
mmenkecc2298e2015-12-07 18:20:182993 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162994 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182995 TestLoadTimingReused(load_timing_info2);
2996 // The load timing after restart should have the same socket ID, and times
2997 // those of the first load timing.
2998 EXPECT_LE(load_timing_info1.receive_headers_end,
2999 load_timing_info2.send_start);
3000 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:323001
bnc691fda62016-08-12 00:43:163002 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:183003 ASSERT_TRUE(response);
3004 EXPECT_FALSE(response->auth_challenge);
3005 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323006
mmenkecc2298e2015-12-07 18:20:183007 std::string response_data;
bnc691fda62016-08-12 00:43:163008 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:323009
Ryan Sleevib8d7ea02018-05-07 20:01:013010 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:163011 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:013012 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:163013 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:183014 }
[email protected]2d2697f92009-02-18 21:00:323015}
3016
3017// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3018// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:013019TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:423020 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323021 request.method = "GET";
bncce36dca22015-04-21 22:11:233022 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103023 request.traffic_annotation =
3024 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323025
danakj1fd259a02016-04-16 03:17:093026 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273027
[email protected]2d2697f92009-02-18 21:00:323028 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163029 MockWrite("GET / HTTP/1.1\r\n"
3030 "Host: www.example.org\r\n"
3031 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323032
bnc691fda62016-08-12 00:43:163033 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233034 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163035 MockWrite("GET / HTTP/1.1\r\n"
3036 "Host: www.example.org\r\n"
3037 "Connection: keep-alive\r\n"
3038 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323039 };
3040
[email protected]2d2697f92009-02-18 21:00:323041 MockRead data_reads1[] = {
3042 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3043 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:313044 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:323045
3046 // Lastly, the server responds with the actual content.
3047 MockRead("HTTP/1.1 200 OK\r\n"),
3048 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503049 MockRead("Content-Length: 5\r\n\r\n"),
3050 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323051 };
3052
[email protected]2d0a4f92011-05-05 16:38:463053 // An incorrect reconnect would cause this to be read.
3054 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063055 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463056 };
3057
Ryan Sleevib8d7ea02018-05-07 20:01:013058 StaticSocketDataProvider data1(data_reads1, data_writes1);
3059 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073060 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3061 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323062
[email protected]49639fa2011-12-20 23:22:413063 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323064
bnc691fda62016-08-12 00:43:163065 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203066 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013067 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323068
3069 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013070 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323071
bnc691fda62016-08-12 00:43:163072 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523073 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043074 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323075
[email protected]49639fa2011-12-20 23:22:413076 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323077
bnc691fda62016-08-12 00:43:163078 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013079 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323080
3081 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013082 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323083
bnc691fda62016-08-12 00:43:163084 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523085 ASSERT_TRUE(response);
3086 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503087 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323088}
3089
3090// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3091// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:013092TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:423093 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323094 request.method = "GET";
bncce36dca22015-04-21 22:11:233095 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103096 request.traffic_annotation =
3097 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323098
danakj1fd259a02016-04-16 03:17:093099 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273100
[email protected]2d2697f92009-02-18 21:00:323101 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163102 MockWrite("GET / HTTP/1.1\r\n"
3103 "Host: www.example.org\r\n"
3104 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323105
bnc691fda62016-08-12 00:43:163106 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233107 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163108 MockWrite("GET / HTTP/1.1\r\n"
3109 "Host: www.example.org\r\n"
3110 "Connection: keep-alive\r\n"
3111 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323112 };
3113
3114 // Respond with 5 kb of response body.
3115 std::string large_body_string("Unauthorized");
3116 large_body_string.append(5 * 1024, ' ');
3117 large_body_string.append("\r\n");
3118
3119 MockRead data_reads1[] = {
3120 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3121 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3122 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3123 // 5134 = 12 + 5 * 1024 + 2
3124 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063125 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:323126
3127 // Lastly, the server responds with the actual content.
3128 MockRead("HTTP/1.1 200 OK\r\n"),
3129 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503130 MockRead("Content-Length: 5\r\n\r\n"),
3131 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323132 };
3133
[email protected]2d0a4f92011-05-05 16:38:463134 // An incorrect reconnect would cause this to be read.
3135 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063136 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463137 };
3138
Ryan Sleevib8d7ea02018-05-07 20:01:013139 StaticSocketDataProvider data1(data_reads1, data_writes1);
3140 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073141 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3142 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323143
[email protected]49639fa2011-12-20 23:22:413144 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323145
bnc691fda62016-08-12 00:43:163146 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203147 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013148 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323149
3150 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013151 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323152
bnc691fda62016-08-12 00:43:163153 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523154 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043155 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323156
[email protected]49639fa2011-12-20 23:22:413157 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323158
bnc691fda62016-08-12 00:43:163159 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013160 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323161
3162 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013163 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323164
bnc691fda62016-08-12 00:43:163165 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523166 ASSERT_TRUE(response);
3167 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503168 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323169}
3170
3171// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:313172// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:013173TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:313174 HttpRequestInfo request;
3175 request.method = "GET";
bncce36dca22015-04-21 22:11:233176 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103177 request.traffic_annotation =
3178 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313179
danakj1fd259a02016-04-16 03:17:093180 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273181
[email protected]11203f012009-11-12 23:02:313182 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233183 MockWrite(
3184 "GET / HTTP/1.1\r\n"
3185 "Host: www.example.org\r\n"
3186 "Connection: keep-alive\r\n\r\n"),
3187 // This simulates the seemingly successful write to a closed connection
3188 // if the bug is not fixed.
3189 MockWrite(
3190 "GET / HTTP/1.1\r\n"
3191 "Host: www.example.org\r\n"
3192 "Connection: keep-alive\r\n"
3193 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313194 };
3195
3196 MockRead data_reads1[] = {
3197 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3198 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3199 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3200 MockRead("Content-Length: 14\r\n\r\n"),
3201 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063202 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313203 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063204 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313205 };
3206
bnc691fda62016-08-12 00:43:163207 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313208 // be issuing -- the final header line contains the credentials.
3209 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233210 MockWrite(
3211 "GET / HTTP/1.1\r\n"
3212 "Host: www.example.org\r\n"
3213 "Connection: keep-alive\r\n"
3214 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313215 };
3216
3217 // Lastly, the server responds with the actual content.
3218 MockRead data_reads2[] = {
3219 MockRead("HTTP/1.1 200 OK\r\n"),
3220 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503221 MockRead("Content-Length: 5\r\n\r\n"),
3222 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313223 };
3224
Ryan Sleevib8d7ea02018-05-07 20:01:013225 StaticSocketDataProvider data1(data_reads1, data_writes1);
3226 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:073227 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3228 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313229
[email protected]49639fa2011-12-20 23:22:413230 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313231
bnc691fda62016-08-12 00:43:163232 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203233 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013234 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313235
3236 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013237 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313238
bnc691fda62016-08-12 00:43:163239 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523240 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043241 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313242
[email protected]49639fa2011-12-20 23:22:413243 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313244
bnc691fda62016-08-12 00:43:163245 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013246 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313247
3248 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013249 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313250
bnc691fda62016-08-12 00:43:163251 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523252 ASSERT_TRUE(response);
3253 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503254 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313255}
3256
[email protected]394816e92010-08-03 07:38:593257// Test the request-challenge-retry sequence for basic auth, over a connection
3258// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013259TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013260 HttpRequestInfo request;
3261 request.method = "GET";
bncce36dca22015-04-21 22:11:233262 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013263 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293264 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103265 request.traffic_annotation =
3266 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013267
3268 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593269 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493270 ProxyResolutionService::CreateFixedFromPacResult(
3271 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513272 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013273 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093274 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013275
3276 // Since we have proxy, should try to establish tunnel.
3277 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543278 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173279 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543280 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013281 };
3282
mmenkee71e15332015-10-07 16:39:543283 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013284 // connection.
3285 MockRead data_reads1[] = {
3286 // No credentials.
3287 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3288 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543289 };
ttuttle34f63b52015-03-05 04:33:013290
mmenkee71e15332015-10-07 16:39:543291 // Since the first connection couldn't be reused, need to establish another
3292 // once given credentials.
3293 MockWrite data_writes2[] = {
3294 // After calling trans->RestartWithAuth(), this is the request we should
3295 // be issuing -- the final header line contains the credentials.
3296 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173297 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543298 "Proxy-Connection: keep-alive\r\n"
3299 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3300
3301 MockWrite("GET / HTTP/1.1\r\n"
3302 "Host: www.example.org\r\n"
3303 "Connection: keep-alive\r\n\r\n"),
3304 };
3305
3306 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013307 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3308
3309 MockRead("HTTP/1.1 200 OK\r\n"),
3310 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3311 MockRead("Content-Length: 5\r\n\r\n"),
3312 MockRead(SYNCHRONOUS, "hello"),
3313 };
3314
Ryan Sleevib8d7ea02018-05-07 20:01:013315 StaticSocketDataProvider data1(data_reads1, data_writes1);
ttuttle34f63b52015-03-05 04:33:013316 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013317 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543318 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013319 SSLSocketDataProvider ssl(ASYNC, OK);
3320 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3321
3322 TestCompletionCallback callback1;
3323
bnc87dcefc2017-05-25 12:47:583324 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193325 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013326
3327 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013329
3330 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013331 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463332 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013333 log.GetEntries(&entries);
3334 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003335 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3336 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013337 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003338 entries, pos,
3339 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3340 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013341
3342 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523343 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013344 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523345 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013346 EXPECT_EQ(407, response->headers->response_code());
3347 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3348 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3349
3350 LoadTimingInfo load_timing_info;
3351 // CONNECT requests and responses are handled at the connect job level, so
3352 // the transaction does not yet have a connection.
3353 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3354
3355 TestCompletionCallback callback2;
3356
3357 rv =
3358 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013359 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013360
3361 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013362 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013363
3364 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523365 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013366
3367 EXPECT_TRUE(response->headers->IsKeepAlive());
3368 EXPECT_EQ(200, response->headers->response_code());
3369 EXPECT_EQ(5, response->headers->GetContentLength());
3370 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3371
3372 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523373 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013374
3375 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3376 TestLoadTimingNotReusedWithPac(load_timing_info,
3377 CONNECT_TIMING_HAS_SSL_TIMES);
3378
3379 trans.reset();
3380 session->CloseAllConnections();
3381}
3382
3383// Test the request-challenge-retry sequence for basic auth, over a connection
3384// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013385TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593386 HttpRequestInfo request;
3387 request.method = "GET";
bncce36dca22015-04-21 22:11:233388 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593389 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293390 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103391 request.traffic_annotation =
3392 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593393
[email protected]cb9bf6ca2011-01-28 13:15:273394 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593395 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493396 ProxyResolutionService::CreateFixedFromPacResult(
3397 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513398 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073399 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093400 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273401
[email protected]394816e92010-08-03 07:38:593402 // Since we have proxy, should try to establish tunnel.
3403 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543404 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173405 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543406 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113407 };
3408
mmenkee71e15332015-10-07 16:39:543409 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083410 // connection.
3411 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543412 // No credentials.
3413 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3414 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3415 MockRead("Proxy-Connection: close\r\n\r\n"),
3416 };
mmenkee0b5c882015-08-26 20:29:113417
mmenkee71e15332015-10-07 16:39:543418 MockWrite data_writes2[] = {
3419 // After calling trans->RestartWithAuth(), this is the request we should
3420 // be issuing -- the final header line contains the credentials.
3421 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173422 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543423 "Proxy-Connection: keep-alive\r\n"
3424 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083425
mmenkee71e15332015-10-07 16:39:543426 MockWrite("GET / HTTP/1.1\r\n"
3427 "Host: www.example.org\r\n"
3428 "Connection: keep-alive\r\n\r\n"),
3429 };
3430
3431 MockRead data_reads2[] = {
3432 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3433
3434 MockRead("HTTP/1.1 200 OK\r\n"),
3435 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3436 MockRead("Content-Length: 5\r\n\r\n"),
3437 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593438 };
3439
Ryan Sleevib8d7ea02018-05-07 20:01:013440 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073441 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013442 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543443 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063444 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073445 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593446
[email protected]49639fa2011-12-20 23:22:413447 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593448
bnc87dcefc2017-05-25 12:47:583449 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193450 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503451
[email protected]49639fa2011-12-20 23:22:413452 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013453 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593454
3455 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013456 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463457 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403458 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593459 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003460 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3461 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593462 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403463 entries, pos,
mikecirone8b85c432016-09-08 19:11:003464 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3465 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593466
3467 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523468 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013469 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523470 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593471 EXPECT_EQ(407, response->headers->response_code());
3472 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043473 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593474
[email protected]029c83b62013-01-24 05:28:203475 LoadTimingInfo load_timing_info;
3476 // CONNECT requests and responses are handled at the connect job level, so
3477 // the transaction does not yet have a connection.
3478 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3479
[email protected]49639fa2011-12-20 23:22:413480 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593481
[email protected]49639fa2011-12-20 23:22:413482 rv = trans->RestartWithAuth(
3483 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013484 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593485
3486 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013487 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593488
3489 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523490 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593491
3492 EXPECT_TRUE(response->headers->IsKeepAlive());
3493 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503494 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593495 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3496
3497 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523498 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503499
[email protected]029c83b62013-01-24 05:28:203500 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3501 TestLoadTimingNotReusedWithPac(load_timing_info,
3502 CONNECT_TIMING_HAS_SSL_TIMES);
3503
[email protected]0b0bf032010-09-21 18:08:503504 trans.reset();
[email protected]102e27c2011-02-23 01:01:313505 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593506}
3507
[email protected]11203f012009-11-12 23:02:313508// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013509// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013510TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233511 // On the second pass, the body read of the auth challenge is synchronous, so
3512 // IsConnectedAndIdle returns false. The socket should still be drained and
3513 // reused. See http://crbug.com/544255.
3514 for (int i = 0; i < 2; ++i) {
3515 HttpRequestInfo request;
3516 request.method = "GET";
3517 request.url = GURL("https://www.example.org/");
3518 // Ensure that proxy authentication is attempted even
3519 // when the no authentication data flag is set.
3520 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103521 request.traffic_annotation =
3522 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013523
mmenked39192ee2015-12-09 00:57:233524 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593525 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493526 ProxyResolutionService::CreateFixed("myproxy:70",
3527 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233528 BoundTestNetLog log;
3529 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093530 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013531
bnc691fda62016-08-12 00:43:163532 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013533
mmenked39192ee2015-12-09 00:57:233534 // Since we have proxy, should try to establish tunnel.
3535 MockWrite data_writes1[] = {
3536 MockWrite(ASYNC, 0,
3537 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3538 "Host: www.example.org:443\r\n"
3539 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013540
bnc691fda62016-08-12 00:43:163541 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233542 // be issuing -- the final header line contains the credentials.
3543 MockWrite(ASYNC, 3,
3544 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3545 "Host: www.example.org:443\r\n"
3546 "Proxy-Connection: keep-alive\r\n"
3547 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3548 };
ttuttle34f63b52015-03-05 04:33:013549
mmenked39192ee2015-12-09 00:57:233550 // The proxy responds to the connect with a 407, using a persistent
3551 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3552 MockRead data_reads1[] = {
3553 // No credentials.
3554 MockRead(ASYNC, 1,
3555 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3556 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3557 "Proxy-Connection: keep-alive\r\n"
3558 "Content-Length: 10\r\n\r\n"),
3559 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013560
mmenked39192ee2015-12-09 00:57:233561 // Wrong credentials (wrong password).
3562 MockRead(ASYNC, 4,
3563 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3564 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3565 "Proxy-Connection: keep-alive\r\n"
3566 "Content-Length: 10\r\n\r\n"),
3567 // No response body because the test stops reading here.
3568 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3569 };
ttuttle34f63b52015-03-05 04:33:013570
Ryan Sleevib8d7ea02018-05-07 20:01:013571 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233572 data1.set_busy_before_sync_reads(true);
3573 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013574
mmenked39192ee2015-12-09 00:57:233575 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013576
bnc691fda62016-08-12 00:43:163577 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013578 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013579
mmenked39192ee2015-12-09 00:57:233580 TestNetLogEntry::List entries;
3581 log.GetEntries(&entries);
3582 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003583 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3584 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233585 ExpectLogContainsSomewhere(
3586 entries, pos,
mikecirone8b85c432016-09-08 19:11:003587 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3588 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013589
bnc691fda62016-08-12 00:43:163590 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233591 ASSERT_TRUE(response);
3592 ASSERT_TRUE(response->headers);
3593 EXPECT_TRUE(response->headers->IsKeepAlive());
3594 EXPECT_EQ(407, response->headers->response_code());
3595 EXPECT_EQ(10, response->headers->GetContentLength());
3596 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3597 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013598
mmenked39192ee2015-12-09 00:57:233599 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013600
mmenked39192ee2015-12-09 00:57:233601 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163602 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3603 callback2.callback());
robpercival214763f2016-07-01 23:27:013604 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013605
bnc691fda62016-08-12 00:43:163606 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233607 ASSERT_TRUE(response);
3608 ASSERT_TRUE(response->headers);
3609 EXPECT_TRUE(response->headers->IsKeepAlive());
3610 EXPECT_EQ(407, response->headers->response_code());
3611 EXPECT_EQ(10, response->headers->GetContentLength());
3612 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3613 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013614
mmenked39192ee2015-12-09 00:57:233615 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3616 // out of scope.
3617 session->CloseAllConnections();
3618 }
ttuttle34f63b52015-03-05 04:33:013619}
3620
3621// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3622// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013623TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233624 // On the second pass, the body read of the auth challenge is synchronous, so
3625 // IsConnectedAndIdle returns false. The socket should still be drained and
3626 // reused. See http://crbug.com/544255.
3627 for (int i = 0; i < 2; ++i) {
3628 HttpRequestInfo request;
3629 request.method = "GET";
3630 request.url = GURL("https://www.example.org/");
3631 // Ensure that proxy authentication is attempted even
3632 // when the no authentication data flag is set.
3633 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103634 request.traffic_annotation =
3635 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233636
3637 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593638 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493639 ProxyResolutionService::CreateFixed("myproxy:70",
3640 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233641 BoundTestNetLog log;
3642 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093643 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233644
bnc691fda62016-08-12 00:43:163645 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233646
3647 // Since we have proxy, should try to establish tunnel.
3648 MockWrite data_writes1[] = {
3649 MockWrite(ASYNC, 0,
3650 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3651 "Host: www.example.org:443\r\n"
3652 "Proxy-Connection: keep-alive\r\n\r\n"),
3653
bnc691fda62016-08-12 00:43:163654 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233655 // be issuing -- the final header line contains the credentials.
3656 MockWrite(ASYNC, 3,
3657 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3658 "Host: www.example.org:443\r\n"
3659 "Proxy-Connection: keep-alive\r\n"
3660 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3661 };
3662
3663 // The proxy responds to the connect with a 407, using a persistent
3664 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3665 MockRead data_reads1[] = {
3666 // No credentials.
3667 MockRead(ASYNC, 1,
3668 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3669 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3670 "Content-Length: 10\r\n\r\n"),
3671 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3672
3673 // Wrong credentials (wrong password).
3674 MockRead(ASYNC, 4,
3675 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3676 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3677 "Content-Length: 10\r\n\r\n"),
3678 // No response body because the test stops reading here.
3679 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3680 };
3681
Ryan Sleevib8d7ea02018-05-07 20:01:013682 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233683 data1.set_busy_before_sync_reads(true);
3684 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3685
3686 TestCompletionCallback callback1;
3687
bnc691fda62016-08-12 00:43:163688 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013689 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233690
3691 TestNetLogEntry::List entries;
3692 log.GetEntries(&entries);
3693 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003694 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3695 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233696 ExpectLogContainsSomewhere(
3697 entries, pos,
mikecirone8b85c432016-09-08 19:11:003698 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3699 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233700
bnc691fda62016-08-12 00:43:163701 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233702 ASSERT_TRUE(response);
3703 ASSERT_TRUE(response->headers);
3704 EXPECT_TRUE(response->headers->IsKeepAlive());
3705 EXPECT_EQ(407, response->headers->response_code());
3706 EXPECT_EQ(10, response->headers->GetContentLength());
3707 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3708 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3709
3710 TestCompletionCallback callback2;
3711
3712 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163713 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3714 callback2.callback());
robpercival214763f2016-07-01 23:27:013715 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233716
bnc691fda62016-08-12 00:43:163717 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233718 ASSERT_TRUE(response);
3719 ASSERT_TRUE(response->headers);
3720 EXPECT_TRUE(response->headers->IsKeepAlive());
3721 EXPECT_EQ(407, response->headers->response_code());
3722 EXPECT_EQ(10, response->headers->GetContentLength());
3723 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3724 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3725
3726 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3727 // out of scope.
3728 session->CloseAllConnections();
3729 }
3730}
3731
3732// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3733// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3734// the case the server sends extra data on the original socket, so it can't be
3735// reused.
bncd16676a2016-07-20 16:23:013736TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273737 HttpRequestInfo request;
3738 request.method = "GET";
bncce36dca22015-04-21 22:11:233739 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273740 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293741 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103742 request.traffic_annotation =
3743 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273744
[email protected]2d2697f92009-02-18 21:00:323745 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593746 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493747 ProxyResolutionService::CreateFixedFromPacResult(
3748 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513749 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073750 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093751 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323752
[email protected]2d2697f92009-02-18 21:00:323753 // Since we have proxy, should try to establish tunnel.
3754 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233755 MockWrite(ASYNC, 0,
3756 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173757 "Host: www.example.org:443\r\n"
3758 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233759 };
[email protected]2d2697f92009-02-18 21:00:323760
mmenked39192ee2015-12-09 00:57:233761 // The proxy responds to the connect with a 407, using a persistent, but sends
3762 // extra data, so the socket cannot be reused.
3763 MockRead data_reads1[] = {
3764 // No credentials.
3765 MockRead(ASYNC, 1,
3766 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3767 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3768 "Content-Length: 10\r\n\r\n"),
3769 MockRead(SYNCHRONOUS, 2, "0123456789"),
3770 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3771 };
3772
3773 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233774 // After calling trans->RestartWithAuth(), this is the request we should
3775 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233776 MockWrite(ASYNC, 0,
3777 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173778 "Host: www.example.org:443\r\n"
3779 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233780 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3781
3782 MockWrite(ASYNC, 2,
3783 "GET / HTTP/1.1\r\n"
3784 "Host: www.example.org\r\n"
3785 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323786 };
3787
mmenked39192ee2015-12-09 00:57:233788 MockRead data_reads2[] = {
3789 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323790
mmenked39192ee2015-12-09 00:57:233791 MockRead(ASYNC, 3,
3792 "HTTP/1.1 200 OK\r\n"
3793 "Content-Type: text/html; charset=iso-8859-1\r\n"
3794 "Content-Length: 5\r\n\r\n"),
3795 // No response body because the test stops reading here.
3796 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323797 };
3798
Ryan Sleevib8d7ea02018-05-07 20:01:013799 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233800 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073801 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013802 SequencedSocketData data2(data_reads2, data_writes2);
mmenked39192ee2015-12-09 00:57:233803 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3804 SSLSocketDataProvider ssl(ASYNC, OK);
3805 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323806
[email protected]49639fa2011-12-20 23:22:413807 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323808
bnc87dcefc2017-05-25 12:47:583809 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193810 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323811
mmenked39192ee2015-12-09 00:57:233812 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013813 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233814
mmenke43758e62015-05-04 21:09:463815 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403816 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393817 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003818 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3819 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393820 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403821 entries, pos,
mikecirone8b85c432016-09-08 19:11:003822 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3823 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323824
[email protected]1c773ea12009-04-28 19:58:423825 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243826 ASSERT_TRUE(response);
3827 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323828 EXPECT_TRUE(response->headers->IsKeepAlive());
3829 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423830 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043831 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323832
mmenked39192ee2015-12-09 00:57:233833 LoadTimingInfo load_timing_info;
3834 // CONNECT requests and responses are handled at the connect job level, so
3835 // the transaction does not yet have a connection.
3836 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3837
[email protected]49639fa2011-12-20 23:22:413838 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323839
mmenked39192ee2015-12-09 00:57:233840 rv =
3841 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013842 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323843
[email protected]2d2697f92009-02-18 21:00:323844 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233845 EXPECT_EQ(200, response->headers->response_code());
3846 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423847 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133848
mmenked39192ee2015-12-09 00:57:233849 // The password prompt info should not be set.
3850 EXPECT_FALSE(response->auth_challenge);
3851
3852 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3853 TestLoadTimingNotReusedWithPac(load_timing_info,
3854 CONNECT_TIMING_HAS_SSL_TIMES);
3855
3856 trans.reset();
[email protected]102e27c2011-02-23 01:01:313857 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323858}
3859
mmenkee71e15332015-10-07 16:39:543860// Test the case a proxy closes a socket while the challenge body is being
3861// drained.
bncd16676a2016-07-20 16:23:013862TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543863 HttpRequestInfo request;
3864 request.method = "GET";
3865 request.url = GURL("https://www.example.org/");
3866 // Ensure that proxy authentication is attempted even
3867 // when the no authentication data flag is set.
3868 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103869 request.traffic_annotation =
3870 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543871
3872 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493873 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3874 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093875 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543876
bnc691fda62016-08-12 00:43:163877 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543878
3879 // Since we have proxy, should try to establish tunnel.
3880 MockWrite data_writes1[] = {
3881 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173882 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543883 "Proxy-Connection: keep-alive\r\n\r\n"),
3884 };
3885
3886 // The proxy responds to the connect with a 407, using a persistent
3887 // connection.
3888 MockRead data_reads1[] = {
3889 // No credentials.
3890 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3891 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3892 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3893 // Server hands up in the middle of the body.
3894 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3895 };
3896
3897 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163898 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543899 // be issuing -- the final header line contains the credentials.
3900 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173901 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543902 "Proxy-Connection: keep-alive\r\n"
3903 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3904
3905 MockWrite("GET / HTTP/1.1\r\n"
3906 "Host: www.example.org\r\n"
3907 "Connection: keep-alive\r\n\r\n"),
3908 };
3909
3910 MockRead data_reads2[] = {
3911 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3912
3913 MockRead("HTTP/1.1 200 OK\r\n"),
3914 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3915 MockRead("Content-Length: 5\r\n\r\n"),
3916 MockRead(SYNCHRONOUS, "hello"),
3917 };
3918
Ryan Sleevib8d7ea02018-05-07 20:01:013919 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenkee71e15332015-10-07 16:39:543920 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013921 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543922 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3923 SSLSocketDataProvider ssl(ASYNC, OK);
3924 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3925
3926 TestCompletionCallback callback;
3927
tfarina42834112016-09-22 13:38:203928 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013929 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543930
bnc691fda62016-08-12 00:43:163931 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543932 ASSERT_TRUE(response);
3933 ASSERT_TRUE(response->headers);
3934 EXPECT_TRUE(response->headers->IsKeepAlive());
3935 EXPECT_EQ(407, response->headers->response_code());
3936 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3937
bnc691fda62016-08-12 00:43:163938 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013939 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543940
bnc691fda62016-08-12 00:43:163941 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543942 ASSERT_TRUE(response);
3943 ASSERT_TRUE(response->headers);
3944 EXPECT_TRUE(response->headers->IsKeepAlive());
3945 EXPECT_EQ(200, response->headers->response_code());
3946 std::string body;
bnc691fda62016-08-12 00:43:163947 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543948 EXPECT_EQ("hello", body);
3949}
3950
[email protected]a8e9b162009-03-12 00:06:443951// Test that we don't read the response body when we fail to establish a tunnel,
3952// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013953TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273954 HttpRequestInfo request;
3955 request.method = "GET";
bncce36dca22015-04-21 22:11:233956 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103957 request.traffic_annotation =
3958 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273959
[email protected]a8e9b162009-03-12 00:06:443960 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493961 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3962 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443963
danakj1fd259a02016-04-16 03:17:093964 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443965
bnc691fda62016-08-12 00:43:163966 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443967
[email protected]a8e9b162009-03-12 00:06:443968 // Since we have proxy, should try to establish tunnel.
3969 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173970 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3971 "Host: www.example.org:443\r\n"
3972 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443973 };
3974
3975 // The proxy responds to the connect with a 407.
3976 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243977 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3978 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3979 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233980 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243981 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443982 };
3983
Ryan Sleevib8d7ea02018-05-07 20:01:013984 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:073985 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443986
[email protected]49639fa2011-12-20 23:22:413987 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443988
tfarina42834112016-09-22 13:38:203989 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013990 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443991
3992 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013993 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443994
bnc691fda62016-08-12 00:43:163995 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243996 ASSERT_TRUE(response);
3997 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443998 EXPECT_TRUE(response->headers->IsKeepAlive());
3999 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:424000 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:444001
4002 std::string response_data;
bnc691fda62016-08-12 00:43:164003 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014004 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:184005
4006 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:314007 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:444008}
4009
ttuttle7933c112015-01-06 00:55:244010// Test that we don't pass extraneous headers from the proxy's response to the
4011// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:014012TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:244013 HttpRequestInfo request;
4014 request.method = "GET";
bncce36dca22015-04-21 22:11:234015 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104016 request.traffic_annotation =
4017 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244018
4019 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494020 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4021 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244022
danakj1fd259a02016-04-16 03:17:094023 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:244024
bnc691fda62016-08-12 00:43:164025 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:244026
4027 // Since we have proxy, should try to establish tunnel.
4028 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:174029 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4030 "Host: www.example.org:443\r\n"
4031 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:244032 };
4033
4034 // The proxy responds to the connect with a 407.
4035 MockRead data_reads[] = {
4036 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4037 MockRead("X-Foo: bar\r\n"),
4038 MockRead("Set-Cookie: foo=bar\r\n"),
4039 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4040 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:234041 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:244042 };
4043
Ryan Sleevib8d7ea02018-05-07 20:01:014044 StaticSocketDataProvider data(data_reads, data_writes);
ttuttle7933c112015-01-06 00:55:244045 session_deps_.socket_factory->AddSocketDataProvider(&data);
4046
4047 TestCompletionCallback callback;
4048
tfarina42834112016-09-22 13:38:204049 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014050 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:244051
4052 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014053 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:244054
bnc691fda62016-08-12 00:43:164055 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244056 ASSERT_TRUE(response);
4057 ASSERT_TRUE(response->headers);
4058 EXPECT_TRUE(response->headers->IsKeepAlive());
4059 EXPECT_EQ(407, response->headers->response_code());
4060 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4061 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
4062 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
4063
4064 std::string response_data;
bnc691fda62016-08-12 00:43:164065 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014066 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:244067
4068 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
4069 session->CloseAllConnections();
4070}
4071
[email protected]8fdbcd22010-05-05 02:54:524072// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
4073// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:014074TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:524075 HttpRequestInfo request;
4076 request.method = "GET";
bncce36dca22015-04-21 22:11:234077 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104078 request.traffic_annotation =
4079 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:524080
[email protected]cb9bf6ca2011-01-28 13:15:274081 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:094082 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:164083 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:274084
[email protected]8fdbcd22010-05-05 02:54:524085 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234086 MockWrite(
4087 "GET / HTTP/1.1\r\n"
4088 "Host: www.example.org\r\n"
4089 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:524090 };
4091
4092 MockRead data_reads1[] = {
4093 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
4094 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4095 // Large content-length -- won't matter, as connection will be reset.
4096 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064097 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:524098 };
4099
Ryan Sleevib8d7ea02018-05-07 20:01:014100 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074101 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:524102
[email protected]49639fa2011-12-20 23:22:414103 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:524104
tfarina42834112016-09-22 13:38:204105 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014106 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:524107
4108 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014109 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:524110}
4111
[email protected]7a67a8152010-11-05 18:31:104112// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
4113// through a non-authenticating proxy. The request should fail with
4114// ERR_UNEXPECTED_PROXY_AUTH.
4115// Note that it is impossible to detect if an HTTP server returns a 407 through
4116// a non-authenticating proxy - there is nothing to indicate whether the
4117// response came from the proxy or the server, so it is treated as if the proxy
4118// issued the challenge.
bncd16676a2016-07-20 16:23:014119TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:274120 HttpRequestInfo request;
4121 request.method = "GET";
bncce36dca22015-04-21 22:11:234122 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104123 request.traffic_annotation =
4124 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274125
Ramin Halavatica8d5252018-03-12 05:33:494126 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4127 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514128 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074129 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094130 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:104131
[email protected]7a67a8152010-11-05 18:31:104132 // Since we have proxy, should try to establish tunnel.
4133 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174134 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4135 "Host: www.example.org:443\r\n"
4136 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104137
rsleevidb16bb02015-11-12 23:47:174138 MockWrite("GET / HTTP/1.1\r\n"
4139 "Host: www.example.org\r\n"
4140 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104141 };
4142
4143 MockRead data_reads1[] = {
4144 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4145
4146 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
4147 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4148 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:064149 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:104150 };
4151
Ryan Sleevib8d7ea02018-05-07 20:01:014152 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074153 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064154 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074155 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:104156
[email protected]49639fa2011-12-20 23:22:414157 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:104158
bnc691fda62016-08-12 00:43:164159 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:104160
bnc691fda62016-08-12 00:43:164161 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014162 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:104163
4164 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014165 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464166 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404167 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104168 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004169 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4170 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104171 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404172 entries, pos,
mikecirone8b85c432016-09-08 19:11:004173 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4174 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104175}
[email protected]2df19bb2010-08-25 20:13:464176
mmenke2a1781d2015-10-07 19:25:334177// Test a proxy auth scheme that allows default credentials and a proxy server
4178// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014179TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334180 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4181 HttpRequestInfo request;
4182 request.method = "GET";
4183 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104184 request.traffic_annotation =
4185 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334186
4187 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594188 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494189 ProxyResolutionService::CreateFixedFromPacResult(
4190 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334191
Jeremy Roman0579ed62017-08-29 15:56:194192 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334193 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194194 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334195 mock_handler->set_allows_default_credentials(true);
4196 auth_handler_factory->AddMockHandler(mock_handler.release(),
4197 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484198 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334199
4200 // Add NetLog just so can verify load timing information gets a NetLog ID.
4201 NetLog net_log;
4202 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094203 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334204
4205 // Since we have proxy, should try to establish tunnel.
4206 MockWrite data_writes1[] = {
4207 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174208 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334209 "Proxy-Connection: keep-alive\r\n\r\n"),
4210 };
4211
4212 // The proxy responds to the connect with a 407, using a non-persistent
4213 // connection.
4214 MockRead data_reads1[] = {
4215 // No credentials.
4216 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4217 MockRead("Proxy-Authenticate: Mock\r\n"),
4218 MockRead("Proxy-Connection: close\r\n\r\n"),
4219 };
4220
4221 // Since the first connection couldn't be reused, need to establish another
4222 // once given credentials.
4223 MockWrite data_writes2[] = {
4224 // After calling trans->RestartWithAuth(), this is the request we should
4225 // be issuing -- the final header line contains the credentials.
4226 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174227 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334228 "Proxy-Connection: keep-alive\r\n"
4229 "Proxy-Authorization: auth_token\r\n\r\n"),
4230
4231 MockWrite("GET / HTTP/1.1\r\n"
4232 "Host: www.example.org\r\n"
4233 "Connection: keep-alive\r\n\r\n"),
4234 };
4235
4236 MockRead data_reads2[] = {
4237 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4238
4239 MockRead("HTTP/1.1 200 OK\r\n"),
4240 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4241 MockRead("Content-Length: 5\r\n\r\n"),
4242 MockRead(SYNCHRONOUS, "hello"),
4243 };
4244
Ryan Sleevib8d7ea02018-05-07 20:01:014245 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334246 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014247 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334248 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4249 SSLSocketDataProvider ssl(ASYNC, OK);
4250 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4251
bnc87dcefc2017-05-25 12:47:584252 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194253 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334254
4255 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204256 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014257 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334258
4259 const HttpResponseInfo* response = trans->GetResponseInfo();
4260 ASSERT_TRUE(response);
4261 ASSERT_TRUE(response->headers);
4262 EXPECT_FALSE(response->headers->IsKeepAlive());
4263 EXPECT_EQ(407, response->headers->response_code());
4264 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4265 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524266 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334267
4268 LoadTimingInfo load_timing_info;
4269 // CONNECT requests and responses are handled at the connect job level, so
4270 // the transaction does not yet have a connection.
4271 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4272
4273 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014274 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334275 response = trans->GetResponseInfo();
4276 ASSERT_TRUE(response);
4277 ASSERT_TRUE(response->headers);
4278 EXPECT_TRUE(response->headers->IsKeepAlive());
4279 EXPECT_EQ(200, response->headers->response_code());
4280 EXPECT_EQ(5, response->headers->GetContentLength());
4281 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4282
4283 // The password prompt info should not be set.
4284 EXPECT_FALSE(response->auth_challenge);
4285
4286 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4287 TestLoadTimingNotReusedWithPac(load_timing_info,
4288 CONNECT_TIMING_HAS_SSL_TIMES);
4289
4290 trans.reset();
4291 session->CloseAllConnections();
4292}
4293
4294// Test a proxy auth scheme that allows default credentials and a proxy server
4295// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014296TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334297 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4298 HttpRequestInfo request;
4299 request.method = "GET";
4300 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104301 request.traffic_annotation =
4302 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334303
4304 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594305 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494306 ProxyResolutionService::CreateFixedFromPacResult(
4307 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334308
Jeremy Roman0579ed62017-08-29 15:56:194309 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334310 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194311 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334312 mock_handler->set_allows_default_credentials(true);
4313 auth_handler_factory->AddMockHandler(mock_handler.release(),
4314 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484315 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334316
4317 // Add NetLog just so can verify load timing information gets a NetLog ID.
4318 NetLog net_log;
4319 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094320 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334321
4322 // Should try to establish tunnel.
4323 MockWrite data_writes1[] = {
4324 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174325 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334326 "Proxy-Connection: keep-alive\r\n\r\n"),
4327
4328 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174329 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334330 "Proxy-Connection: keep-alive\r\n"
4331 "Proxy-Authorization: auth_token\r\n\r\n"),
4332 };
4333
4334 // The proxy responds to the connect with a 407, using a non-persistent
4335 // connection.
4336 MockRead data_reads1[] = {
4337 // No credentials.
4338 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4339 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4340 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4341 };
4342
4343 // Since the first connection was closed, need to establish another once given
4344 // credentials.
4345 MockWrite data_writes2[] = {
4346 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174347 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334348 "Proxy-Connection: keep-alive\r\n"
4349 "Proxy-Authorization: auth_token\r\n\r\n"),
4350
4351 MockWrite("GET / HTTP/1.1\r\n"
4352 "Host: www.example.org\r\n"
4353 "Connection: keep-alive\r\n\r\n"),
4354 };
4355
4356 MockRead data_reads2[] = {
4357 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4358
4359 MockRead("HTTP/1.1 200 OK\r\n"),
4360 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4361 MockRead("Content-Length: 5\r\n\r\n"),
4362 MockRead(SYNCHRONOUS, "hello"),
4363 };
4364
Ryan Sleevib8d7ea02018-05-07 20:01:014365 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334366 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014367 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334368 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4369 SSLSocketDataProvider ssl(ASYNC, OK);
4370 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4371
bnc87dcefc2017-05-25 12:47:584372 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194373 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334374
4375 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204376 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014377 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334378
4379 const HttpResponseInfo* response = trans->GetResponseInfo();
4380 ASSERT_TRUE(response);
4381 ASSERT_TRUE(response->headers);
4382 EXPECT_TRUE(response->headers->IsKeepAlive());
4383 EXPECT_EQ(407, response->headers->response_code());
4384 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4385 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4386 EXPECT_FALSE(response->auth_challenge);
4387
4388 LoadTimingInfo load_timing_info;
4389 // CONNECT requests and responses are handled at the connect job level, so
4390 // the transaction does not yet have a connection.
4391 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4392
4393 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014394 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334395
4396 response = trans->GetResponseInfo();
4397 ASSERT_TRUE(response);
4398 ASSERT_TRUE(response->headers);
4399 EXPECT_TRUE(response->headers->IsKeepAlive());
4400 EXPECT_EQ(200, response->headers->response_code());
4401 EXPECT_EQ(5, response->headers->GetContentLength());
4402 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4403
4404 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524405 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334406
4407 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4408 TestLoadTimingNotReusedWithPac(load_timing_info,
4409 CONNECT_TIMING_HAS_SSL_TIMES);
4410
4411 trans.reset();
4412 session->CloseAllConnections();
4413}
4414
4415// Test a proxy auth scheme that allows default credentials and a proxy server
4416// that hangs up when credentials are initially sent, and hangs up again when
4417// they are retried.
bncd16676a2016-07-20 16:23:014418TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334419 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4420 HttpRequestInfo request;
4421 request.method = "GET";
4422 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104423 request.traffic_annotation =
4424 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334425
4426 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594427 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494428 ProxyResolutionService::CreateFixedFromPacResult(
4429 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334430
Jeremy Roman0579ed62017-08-29 15:56:194431 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334432 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194433 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334434 mock_handler->set_allows_default_credentials(true);
4435 auth_handler_factory->AddMockHandler(mock_handler.release(),
4436 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484437 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334438
4439 // Add NetLog just so can verify load timing information gets a NetLog ID.
4440 NetLog net_log;
4441 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094442 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334443
4444 // Should try to establish tunnel.
4445 MockWrite data_writes1[] = {
4446 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174447 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334448 "Proxy-Connection: keep-alive\r\n\r\n"),
4449
4450 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174451 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334452 "Proxy-Connection: keep-alive\r\n"
4453 "Proxy-Authorization: auth_token\r\n\r\n"),
4454 };
4455
4456 // The proxy responds to the connect with a 407, and then hangs up after the
4457 // second request is sent.
4458 MockRead data_reads1[] = {
4459 // No credentials.
4460 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4461 MockRead("Content-Length: 0\r\n"),
4462 MockRead("Proxy-Connection: keep-alive\r\n"),
4463 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4464 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4465 };
4466
4467 // HttpNetworkTransaction sees a reused connection that was closed with
4468 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4469 // request.
4470 MockWrite data_writes2[] = {
4471 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174472 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334473 "Proxy-Connection: keep-alive\r\n\r\n"),
4474 };
4475
4476 // The proxy, having had more than enough of us, just hangs up.
4477 MockRead data_reads2[] = {
4478 // No credentials.
4479 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4480 };
4481
Ryan Sleevib8d7ea02018-05-07 20:01:014482 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334483 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014484 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334485 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4486
bnc87dcefc2017-05-25 12:47:584487 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194488 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334489
4490 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204491 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014492 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334493
4494 const HttpResponseInfo* response = trans->GetResponseInfo();
4495 ASSERT_TRUE(response);
4496 ASSERT_TRUE(response->headers);
4497 EXPECT_TRUE(response->headers->IsKeepAlive());
4498 EXPECT_EQ(407, response->headers->response_code());
4499 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4500 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4501 EXPECT_FALSE(response->auth_challenge);
4502
4503 LoadTimingInfo load_timing_info;
4504 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4505
4506 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014507 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334508
4509 trans.reset();
4510 session->CloseAllConnections();
4511}
4512
Asanka Herathbc3f8f62018-11-16 23:08:304513// This test exercises an odd edge case where the proxy closes the connection
4514// after the authentication handshake is complete. Presumably this technique is
4515// used in lieu of returning a 403 or 5xx status code when the authentication
4516// succeeds, but the user is not authorized to connect to the destination
4517// server. There's no standard for what a proxy should do to indicate a blocked
4518// site.
4519TEST_F(HttpNetworkTransactionTest,
4520 AuthAllowsDefaultCredentialsTunnelConnectionClosesBeforeBody) {
4521 HttpRequestInfo request;
4522 request.method = "GET";
4523 request.url = GURL("https://www.example.org/");
4524 request.traffic_annotation =
4525 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4526
4527 // Configure against proxy server "myproxy:70".
4528 session_deps_.proxy_resolution_service =
4529 ProxyResolutionService::CreateFixedFromPacResult(
4530 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4531
Steven Valdez0ef94d02018-11-19 23:28:134532 // When TLS 1.3 is enabled, spurious connections are made as part of the SSL
4533 // version interference probes.
4534 // TODO(crbug.com/906668): Correctly handle version interference probes to
4535 // test TLS 1.3.
4536 SSLConfig config;
4537 config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
4538 session_deps_.ssl_config_service =
4539 std::make_unique<TestSSLConfigService>(config);
4540
Asanka Herathbc3f8f62018-11-16 23:08:304541 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
4542 auth_handler_factory->set_do_init_from_challenge(true);
4543
4544 // Create two mock AuthHandlers. This is because the transaction gets retried
4545 // after the first ERR_CONNECTION_CLOSED since it's ambiguous whether there
4546 // was a real network error.
4547 //
4548 // The handlers support both default and explicit credentials. The retry
4549 // mentioned above should be able to reuse the default identity. Thus there
4550 // should never be a need to prompt for explicit credentials.
4551 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
4552 mock_handler->set_allows_default_credentials(true);
4553 mock_handler->set_allows_explicit_credentials(true);
4554 mock_handler->set_connection_based(true);
4555 auth_handler_factory->AddMockHandler(mock_handler.release(),
4556 HttpAuth::AUTH_PROXY);
4557 mock_handler = std::make_unique<HttpAuthHandlerMock>();
4558 mock_handler->set_allows_default_credentials(true);
4559 mock_handler->set_allows_explicit_credentials(true);
4560 mock_handler->set_connection_based(true);
4561 auth_handler_factory->AddMockHandler(mock_handler.release(),
4562 HttpAuth::AUTH_PROXY);
4563 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4564
4565 NetLog net_log;
4566 session_deps_.net_log = &net_log;
4567 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4568
4569 // Data for both sockets.
4570 //
4571 // Writes are for the tunnel establishment attempts and the
4572 // authentication handshake.
4573 MockWrite data_writes1[] = {
4574 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4575 "Host: www.example.org:443\r\n"
4576 "Proxy-Connection: keep-alive\r\n\r\n"),
4577
4578 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4579 "Host: www.example.org:443\r\n"
4580 "Proxy-Connection: keep-alive\r\n"
4581 "Proxy-Authorization: auth_token\r\n\r\n"),
4582
4583 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4584 "Host: www.example.org:443\r\n"
4585 "Proxy-Connection: keep-alive\r\n"
4586 "Proxy-Authorization: auth_token\r\n\r\n"),
4587 };
4588
4589 // The server side of the authentication handshake. Note that the response to
4590 // the final CONNECT request is ERR_CONNECTION_CLOSED.
4591 MockRead data_reads1[] = {
4592 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4593 MockRead("Content-Length: 0\r\n"),
4594 MockRead("Proxy-Connection: keep-alive\r\n"),
4595 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4596
4597 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4598 MockRead("Content-Length: 0\r\n"),
4599 MockRead("Proxy-Connection: keep-alive\r\n"),
4600 MockRead("Proxy-Authenticate: Mock foo\r\n\r\n"),
4601
4602 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4603 };
4604
4605 StaticSocketDataProvider data1(data_reads1, data_writes1);
4606 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4607
4608 // The second socket is for the reconnection attempt. Data is identical to the
4609 // first attempt.
4610 StaticSocketDataProvider data2(data_reads1, data_writes1);
4611 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4612
4613 auto trans =
4614 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4615
4616 TestCompletionCallback callback;
4617 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4618
4619 // Two rounds per handshake. After one retry, the error is propagated up the
4620 // stack.
4621 for (int i = 0; i < 4; ++i) {
4622 EXPECT_THAT(callback.GetResult(rv), IsOk());
4623
4624 const HttpResponseInfo* response = trans->GetResponseInfo();
4625 ASSERT_TRUE(response);
4626 ASSERT_TRUE(response->headers);
4627 EXPECT_EQ(407, response->headers->response_code());
4628 ASSERT_TRUE(trans->IsReadyToRestartForAuth());
4629
4630 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4631 }
4632
4633 // One shall be the number thou shalt retry, and the number of the retrying
4634 // shall be one. Two shalt thou not retry, neither retry thou zero, excepting
4635 // that thou then proceed to one. Three is right out. Once the number one,
4636 // being the first number, be reached, then lobbest thou thy
4637 // ERR_CONNECTION_CLOSED towards they network transaction, who shall snuff it.
4638 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.GetResult(rv));
4639
4640 trans.reset();
4641 session->CloseAllConnections();
4642}
4643
mmenke2a1781d2015-10-07 19:25:334644// Test a proxy auth scheme that allows default credentials and a proxy server
4645// that hangs up when credentials are initially sent, and sends a challenge
4646// again they are retried.
bncd16676a2016-07-20 16:23:014647TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334648 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4649 HttpRequestInfo request;
4650 request.method = "GET";
4651 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104652 request.traffic_annotation =
4653 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334654
4655 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594656 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494657 ProxyResolutionService::CreateFixedFromPacResult(
4658 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334659
Jeremy Roman0579ed62017-08-29 15:56:194660 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334661 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194662 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334663 mock_handler->set_allows_default_credentials(true);
4664 auth_handler_factory->AddMockHandler(mock_handler.release(),
4665 HttpAuth::AUTH_PROXY);
4666 // Add another handler for the second challenge. It supports default
4667 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194668 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334669 mock_handler->set_allows_default_credentials(true);
4670 auth_handler_factory->AddMockHandler(mock_handler.release(),
4671 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484672 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334673
4674 // Add NetLog just so can verify load timing information gets a NetLog ID.
4675 NetLog net_log;
4676 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094677 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334678
4679 // Should try to establish tunnel.
4680 MockWrite data_writes1[] = {
4681 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174682 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334683 "Proxy-Connection: keep-alive\r\n\r\n"),
4684 };
4685
4686 // The proxy responds to the connect with a 407, using a non-persistent
4687 // connection.
4688 MockRead data_reads1[] = {
4689 // No credentials.
4690 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4691 MockRead("Proxy-Authenticate: Mock\r\n"),
4692 MockRead("Proxy-Connection: close\r\n\r\n"),
4693 };
4694
4695 // Since the first connection was closed, need to establish another once given
4696 // credentials.
4697 MockWrite data_writes2[] = {
4698 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174699 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334700 "Proxy-Connection: keep-alive\r\n"
4701 "Proxy-Authorization: auth_token\r\n\r\n"),
4702 };
4703
4704 MockRead data_reads2[] = {
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
Ryan Sleevib8d7ea02018-05-07 20:01:014710 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334711 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014712 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334713 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4714 SSLSocketDataProvider ssl(ASYNC, OK);
4715 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4716
bnc87dcefc2017-05-25 12:47:584717 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194718 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334719
4720 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204721 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014722 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334723
4724 const HttpResponseInfo* response = trans->GetResponseInfo();
4725 ASSERT_TRUE(response);
4726 ASSERT_TRUE(response->headers);
4727 EXPECT_EQ(407, response->headers->response_code());
4728 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4729 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4730 EXPECT_FALSE(response->auth_challenge);
4731
4732 LoadTimingInfo load_timing_info;
4733 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4734
4735 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014736 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334737 response = trans->GetResponseInfo();
4738 ASSERT_TRUE(response);
4739 ASSERT_TRUE(response->headers);
4740 EXPECT_EQ(407, response->headers->response_code());
4741 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4742 EXPECT_TRUE(response->auth_challenge);
4743
4744 trans.reset();
4745 session->CloseAllConnections();
4746}
4747
asankae2257db2016-10-11 22:03:164748// A more nuanced test than GenerateAuthToken test which asserts that
4749// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4750// unnecessarily invalidated, and that if the server co-operates, the
4751// authentication handshake can continue with the same scheme but with a
4752// different identity.
4753TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4754 HttpRequestInfo request;
4755 request.method = "GET";
4756 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104757 request.traffic_annotation =
4758 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164759
Jeremy Roman0579ed62017-08-29 15:56:194760 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164761 auth_handler_factory->set_do_init_from_challenge(true);
4762
4763 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194764 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164765 mock_handler->set_allows_default_credentials(true);
4766 mock_handler->set_allows_explicit_credentials(true);
4767 mock_handler->set_connection_based(true);
4768 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4769 auth_handler_factory->AddMockHandler(mock_handler.release(),
4770 HttpAuth::AUTH_SERVER);
4771
4772 // Add another handler for the second challenge. It supports default
4773 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194774 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164775 mock_handler->set_allows_default_credentials(true);
4776 mock_handler->set_allows_explicit_credentials(true);
4777 mock_handler->set_connection_based(true);
4778 auth_handler_factory->AddMockHandler(mock_handler.release(),
4779 HttpAuth::AUTH_SERVER);
4780 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4781
4782 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4783
4784 MockWrite data_writes1[] = {
4785 MockWrite("GET / HTTP/1.1\r\n"
4786 "Host: www.example.org\r\n"
4787 "Connection: keep-alive\r\n\r\n"),
4788 };
4789
4790 MockRead data_reads1[] = {
4791 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4792 "WWW-Authenticate: Mock\r\n"
4793 "Connection: keep-alive\r\n\r\n"),
4794 };
4795
4796 // Identical to data_writes1[]. The AuthHandler encounters a
4797 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4798 // transaction procceds without an authorization header.
4799 MockWrite data_writes2[] = {
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_reads2[] = {
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 MockWrite data_writes3[] = {
4812 MockWrite("GET / HTTP/1.1\r\n"
4813 "Host: www.example.org\r\n"
4814 "Connection: keep-alive\r\n"
4815 "Authorization: auth_token\r\n\r\n"),
4816 };
4817
4818 MockRead data_reads3[] = {
4819 MockRead("HTTP/1.1 200 OK\r\n"
4820 "Content-Length: 5\r\n"
4821 "Content-Type: text/plain\r\n"
4822 "Connection: keep-alive\r\n\r\n"
4823 "Hello"),
4824 };
4825
Ryan Sleevib8d7ea02018-05-07 20:01:014826 StaticSocketDataProvider data1(data_reads1, data_writes1);
asankae2257db2016-10-11 22:03:164827 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4828
Ryan Sleevib8d7ea02018-05-07 20:01:014829 StaticSocketDataProvider data2(data_reads2, data_writes2);
asankae2257db2016-10-11 22:03:164830 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4831
Ryan Sleevib8d7ea02018-05-07 20:01:014832 StaticSocketDataProvider data3(data_reads3, data_writes3);
asankae2257db2016-10-11 22:03:164833 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4834
bnc87dcefc2017-05-25 12:47:584835 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194836 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164837
4838 TestCompletionCallback callback;
4839 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4840 EXPECT_THAT(callback.GetResult(rv), IsOk());
4841
4842 const HttpResponseInfo* response = trans->GetResponseInfo();
4843 ASSERT_TRUE(response);
4844 ASSERT_TRUE(response->headers);
4845 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4846
4847 // The following three tests assert that an authentication challenge was
4848 // received and that the stack is ready to respond to the challenge using
4849 // ambient credentials.
4850 EXPECT_EQ(401, response->headers->response_code());
4851 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4852 EXPECT_FALSE(response->auth_challenge);
4853
4854 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4855 EXPECT_THAT(callback.GetResult(rv), IsOk());
4856 response = trans->GetResponseInfo();
4857 ASSERT_TRUE(response);
4858 ASSERT_TRUE(response->headers);
4859
4860 // The following three tests assert that an authentication challenge was
4861 // received and that the stack needs explicit credentials before it is ready
4862 // to respond to the challenge.
4863 EXPECT_EQ(401, response->headers->response_code());
4864 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4865 EXPECT_TRUE(response->auth_challenge);
4866
4867 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4868 EXPECT_THAT(callback.GetResult(rv), IsOk());
4869 response = trans->GetResponseInfo();
4870 ASSERT_TRUE(response);
4871 ASSERT_TRUE(response->headers);
4872 EXPECT_EQ(200, response->headers->response_code());
4873
4874 trans.reset();
4875 session->CloseAllConnections();
4876}
4877
Matt Menked1eb6d42018-01-17 04:54:064878// Proxy resolver that returns a proxy with the same host and port for different
4879// schemes, based on the path of the URL being requests.
4880class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4881 public:
4882 SameProxyWithDifferentSchemesProxyResolver() {}
4883 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4884
4885 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4886
4887 static HostPortPair ProxyHostPortPair() {
4888 return HostPortPair::FromString(ProxyHostPortPairAsString());
4889 }
4890
4891 // ProxyResolver implementation.
4892 int GetProxyForURL(const GURL& url,
4893 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:174894 CompletionOnceCallback callback,
Matt Menked1eb6d42018-01-17 04:54:064895 std::unique_ptr<Request>* request,
4896 const NetLogWithSource& /*net_log*/) override {
4897 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574898 results->set_traffic_annotation(
4899 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064900 if (url.path() == "/socks4") {
4901 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4902 return OK;
4903 }
4904 if (url.path() == "/socks5") {
4905 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4906 return OK;
4907 }
4908 if (url.path() == "/http") {
4909 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4910 return OK;
4911 }
4912 if (url.path() == "/https") {
4913 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4914 return OK;
4915 }
Matt Menkee8648fa2019-01-17 16:47:074916 if (url.path() == "/https_trusted") {
4917 results->UseProxyServer(ProxyServer(ProxyServer::SCHEME_HTTPS,
4918 ProxyHostPortPair(),
4919 true /* is_trusted_proxy */));
4920 return OK;
4921 }
Matt Menked1eb6d42018-01-17 04:54:064922 NOTREACHED();
4923 return ERR_NOT_IMPLEMENTED;
4924 }
4925
4926 private:
4927 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4928};
4929
4930class SameProxyWithDifferentSchemesProxyResolverFactory
4931 : public ProxyResolverFactory {
4932 public:
4933 SameProxyWithDifferentSchemesProxyResolverFactory()
4934 : ProxyResolverFactory(false) {}
4935
Lily Houghton99597862018-03-07 16:40:424936 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4937 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:174938 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:424939 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064940 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4941 return OK;
4942 }
4943
4944 private:
4945 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4946};
4947
4948// Check that when different proxy schemes are all applied to a proxy at the
Matt Menkee8648fa2019-01-17 16:47:074949// same address, the connections are not grouped together. i.e., a request to
Matt Menked1eb6d42018-01-17 04:54:064950// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4951// request to foo.com using proxy.com as an HTTP proxy.
4952TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494953 session_deps_.proxy_resolution_service =
4954 std::make_unique<ProxyResolutionService>(
4955 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4956 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4957 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4958 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064959
4960 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4961
4962 MockWrite socks_writes[] = {
4963 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4964 kSOCKS4OkRequestLocalHostPort80Length),
4965 MockWrite(SYNCHRONOUS,
4966 "GET /socks4 HTTP/1.1\r\n"
4967 "Host: test\r\n"
4968 "Connection: keep-alive\r\n\r\n"),
4969 };
4970 MockRead socks_reads[] = {
4971 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4972 MockRead("HTTP/1.0 200 OK\r\n"
4973 "Connection: keep-alive\r\n"
4974 "Content-Length: 15\r\n\r\n"
4975 "SOCKS4 Response"),
4976 };
Ryan Sleevib8d7ea02018-05-07 20:01:014977 StaticSocketDataProvider socks_data(socks_reads, socks_writes);
Matt Menked1eb6d42018-01-17 04:54:064978 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4979
4980 const char kSOCKS5Request[] = {
4981 0x05, // Version
4982 0x01, // Command (CONNECT)
4983 0x00, // Reserved
4984 0x03, // Address type (DOMAINNAME)
4985 0x04, // Length of domain (4)
4986 't', 'e', 's', 't', // Domain string
4987 0x00, 0x50, // 16-bit port (80)
4988 };
4989 MockWrite socks5_writes[] = {
4990 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Avi Drissman4365a4782018-12-28 19:26:244991 MockWrite(ASYNC, kSOCKS5Request, base::size(kSOCKS5Request)),
Matt Menked1eb6d42018-01-17 04:54:064992 MockWrite(SYNCHRONOUS,
4993 "GET /socks5 HTTP/1.1\r\n"
4994 "Host: test\r\n"
4995 "Connection: keep-alive\r\n\r\n"),
4996 };
4997 MockRead socks5_reads[] = {
4998 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4999 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
5000 MockRead("HTTP/1.0 200 OK\r\n"
5001 "Connection: keep-alive\r\n"
5002 "Content-Length: 15\r\n\r\n"
5003 "SOCKS5 Response"),
5004 };
Ryan Sleevib8d7ea02018-05-07 20:01:015005 StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
Matt Menked1eb6d42018-01-17 04:54:065006 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
5007
5008 MockWrite http_writes[] = {
5009 MockWrite(SYNCHRONOUS,
5010 "GET http://test/http HTTP/1.1\r\n"
5011 "Host: test\r\n"
5012 "Proxy-Connection: keep-alive\r\n\r\n"),
5013 };
5014 MockRead http_reads[] = {
5015 MockRead("HTTP/1.1 200 OK\r\n"
5016 "Proxy-Connection: keep-alive\r\n"
5017 "Content-Length: 13\r\n\r\n"
5018 "HTTP Response"),
5019 };
Ryan Sleevib8d7ea02018-05-07 20:01:015020 StaticSocketDataProvider http_data(http_reads, http_writes);
Matt Menked1eb6d42018-01-17 04:54:065021 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
5022
5023 MockWrite https_writes[] = {
5024 MockWrite(SYNCHRONOUS,
5025 "GET http://test/https HTTP/1.1\r\n"
5026 "Host: test\r\n"
5027 "Proxy-Connection: keep-alive\r\n\r\n"),
5028 };
5029 MockRead https_reads[] = {
5030 MockRead("HTTP/1.1 200 OK\r\n"
5031 "Proxy-Connection: keep-alive\r\n"
5032 "Content-Length: 14\r\n\r\n"
5033 "HTTPS Response"),
5034 };
Ryan Sleevib8d7ea02018-05-07 20:01:015035 StaticSocketDataProvider https_data(https_reads, https_writes);
Matt Menked1eb6d42018-01-17 04:54:065036 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
5037 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
5038 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5039
Matt Menkee8648fa2019-01-17 16:47:075040 MockWrite https_trusted_writes[] = {
5041 MockWrite(SYNCHRONOUS,
5042 "GET http://test/https_trusted HTTP/1.1\r\n"
5043 "Host: test\r\n"
5044 "Proxy-Connection: keep-alive\r\n\r\n"),
5045 };
5046 MockRead https_trusted_reads[] = {
5047 MockRead("HTTP/1.1 200 OK\r\n"
5048 "Proxy-Connection: keep-alive\r\n"
5049 "Content-Length: 22\r\n\r\n"
5050 "HTTPS Trusted Response"),
5051 };
5052 StaticSocketDataProvider trusted_https_data(https_trusted_reads,
5053 https_trusted_writes);
5054 session_deps_.socket_factory->AddSocketDataProvider(&trusted_https_data);
5055 SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
5056 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
5057
Matt Menked1eb6d42018-01-17 04:54:065058 struct TestCase {
5059 GURL url;
5060 std::string expected_response;
Matt Menkee8648fa2019-01-17 16:47:075061 // How many idle sockets there should be in the SOCKS 4/5 proxy socket pools
Matt Menked1eb6d42018-01-17 04:54:065062 // after the test.
Matt Menkee8648fa2019-01-17 16:47:075063 int expected_idle_socks4_sockets;
5064 int expected_idle_socks5_sockets;
5065 // How many idle sockets there should be in the HTTP/HTTPS proxy socket
5066 // pools after the test.
Matt Menked1eb6d42018-01-17 04:54:065067 int expected_idle_http_sockets;
Matt Menkee8648fa2019-01-17 16:47:075068 int expected_idle_https_sockets;
5069 // How many idle sockets there should be in the HTTPS proxy socket pool with
5070 // the ProxyServer's |is_trusted_proxy| bit set after the test.
5071 int expected_idle_trusted_https_sockets;
Matt Menked1eb6d42018-01-17 04:54:065072 } const kTestCases[] = {
Matt Menkee8648fa2019-01-17 16:47:075073 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0, 0, 0, 0},
5074 {GURL("http://test/socks5"), "SOCKS5 Response", 1, 1, 0, 0, 0},
5075 {GURL("http://test/http"), "HTTP Response", 1, 1, 1, 0, 0},
5076 {GURL("http://test/https"), "HTTPS Response", 1, 1, 1, 1, 0},
5077 {GURL("http://test/https_trusted"), "HTTPS Trusted Response", 1, 1, 1, 1,
5078 1},
Matt Menked1eb6d42018-01-17 04:54:065079 };
5080
5081 for (const auto& test_case : kTestCases) {
5082 HttpRequestInfo request;
5083 request.method = "GET";
5084 request.url = test_case.url;
Ramin Halavatib5e433e2018-02-07 07:41:105085 request.traffic_annotation =
5086 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:065087 std::unique_ptr<HttpNetworkTransaction> trans =
5088 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
5089 session.get());
5090 TestCompletionCallback callback;
5091 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5092 EXPECT_THAT(callback.GetResult(rv), IsOk());
5093
5094 const HttpResponseInfo* response = trans->GetResponseInfo();
5095 ASSERT_TRUE(response);
5096 ASSERT_TRUE(response->headers);
5097 EXPECT_EQ(200, response->headers->response_code());
5098 std::string response_data;
5099 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
5100 EXPECT_EQ(test_case.expected_response, response_data);
5101
5102 // Return the socket to the socket pool, so can make sure it's not used for
5103 // the next requests.
5104 trans.reset();
5105 base::RunLoop().RunUntilIdle();
5106
5107 // Check the number of idle sockets in the pool, to make sure that used
5108 // sockets are indeed being returned to the socket pool. If each request
5109 // doesn't return an idle socket to the pool, the test would incorrectly
5110 // pass.
Matt Menkee8648fa2019-01-17 16:47:075111 EXPECT_EQ(test_case.expected_idle_socks4_sockets,
5112 session
Matt Menked23ab952019-03-06 00:24:405113 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075114 HttpNetworkSession::NORMAL_SOCKET_POOL,
5115 ProxyServer(ProxyServer::SCHEME_SOCKS4,
5116 SameProxyWithDifferentSchemesProxyResolver::
5117 ProxyHostPortPair()))
5118 ->IdleSocketCount());
5119 EXPECT_EQ(test_case.expected_idle_socks5_sockets,
5120 session
Matt Menked23ab952019-03-06 00:24:405121 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075122 HttpNetworkSession::NORMAL_SOCKET_POOL,
5123 ProxyServer(ProxyServer::SCHEME_SOCKS5,
5124 SameProxyWithDifferentSchemesProxyResolver::
5125 ProxyHostPortPair()))
5126 ->IdleSocketCount());
5127 EXPECT_EQ(test_case.expected_idle_http_sockets,
5128 session
Matt Menked23ab952019-03-06 00:24:405129 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075130 HttpNetworkSession::NORMAL_SOCKET_POOL,
5131 ProxyServer(ProxyServer::SCHEME_HTTP,
5132 SameProxyWithDifferentSchemesProxyResolver::
5133 ProxyHostPortPair()))
5134 ->IdleSocketCount());
5135 EXPECT_EQ(test_case.expected_idle_https_sockets,
5136 session
Matt Menked23ab952019-03-06 00:24:405137 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075138 HttpNetworkSession::NORMAL_SOCKET_POOL,
5139 ProxyServer(ProxyServer::SCHEME_HTTPS,
5140 SameProxyWithDifferentSchemesProxyResolver::
5141 ProxyHostPortPair()))
5142 ->IdleSocketCount());
5143 EXPECT_EQ(test_case.expected_idle_trusted_https_sockets,
5144 session
Matt Menked23ab952019-03-06 00:24:405145 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075146 HttpNetworkSession::NORMAL_SOCKET_POOL,
5147 ProxyServer(ProxyServer::SCHEME_HTTPS,
5148 SameProxyWithDifferentSchemesProxyResolver::
5149 ProxyHostPortPair(),
5150 true /* is_trusted_proxy */))
5151 ->IdleSocketCount());
Matt Menked1eb6d42018-01-17 04:54:065152 }
5153}
5154
[email protected]029c83b62013-01-24 05:28:205155// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:015156TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205157 HttpRequestInfo request1;
5158 request1.method = "GET";
bncce36dca22015-04-21 22:11:235159 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:105160 request1.traffic_annotation =
5161 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205162
5163 HttpRequestInfo request2;
5164 request2.method = "GET";
bncce36dca22015-04-21 22:11:235165 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:105166 request2.traffic_annotation =
5167 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205168
5169 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495170 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5171 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515172 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075173 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095174 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205175
5176 // Since we have proxy, should try to establish tunnel.
5177 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175178 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5179 "Host: www.example.org:443\r\n"
5180 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205181
rsleevidb16bb02015-11-12 23:47:175182 MockWrite("GET /1 HTTP/1.1\r\n"
5183 "Host: www.example.org\r\n"
5184 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205185
rsleevidb16bb02015-11-12 23:47:175186 MockWrite("GET /2 HTTP/1.1\r\n"
5187 "Host: www.example.org\r\n"
5188 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205189 };
5190
5191 // The proxy responds to the connect with a 407, using a persistent
5192 // connection.
5193 MockRead data_reads1[] = {
5194 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5195
5196 MockRead("HTTP/1.1 200 OK\r\n"),
5197 MockRead("Content-Length: 1\r\n\r\n"),
5198 MockRead(SYNCHRONOUS, "1"),
5199
5200 MockRead("HTTP/1.1 200 OK\r\n"),
5201 MockRead("Content-Length: 2\r\n\r\n"),
5202 MockRead(SYNCHRONOUS, "22"),
5203 };
5204
Ryan Sleevib8d7ea02018-05-07 20:01:015205 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075206 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205207 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075208 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205209
5210 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585211 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195212 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205213
5214 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015215 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205216
5217 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015218 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205219
5220 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525221 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:475222 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:525223 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205224 EXPECT_EQ(1, response1->headers->GetContentLength());
5225
5226 LoadTimingInfo load_timing_info1;
5227 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5228 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
5229
5230 trans1.reset();
5231
5232 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585233 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195234 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205235
5236 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015237 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205238
5239 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015240 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205241
5242 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525243 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:475244 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:525245 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205246 EXPECT_EQ(2, response2->headers->GetContentLength());
5247
5248 LoadTimingInfo load_timing_info2;
5249 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5250 TestLoadTimingReused(load_timing_info2);
5251
5252 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5253
5254 trans2.reset();
5255 session->CloseAllConnections();
5256}
5257
5258// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:015259TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205260 HttpRequestInfo request1;
5261 request1.method = "GET";
bncce36dca22015-04-21 22:11:235262 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:105263 request1.traffic_annotation =
5264 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205265
5266 HttpRequestInfo request2;
5267 request2.method = "GET";
bncce36dca22015-04-21 22:11:235268 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:105269 request2.traffic_annotation =
5270 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205271
5272 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595273 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:495274 ProxyResolutionService::CreateFixedFromPacResult(
5275 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515276 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075277 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095278 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205279
5280 // Since we have proxy, should try to establish tunnel.
5281 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175282 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5283 "Host: www.example.org:443\r\n"
5284 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205285
rsleevidb16bb02015-11-12 23:47:175286 MockWrite("GET /1 HTTP/1.1\r\n"
5287 "Host: www.example.org\r\n"
5288 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205289
rsleevidb16bb02015-11-12 23:47:175290 MockWrite("GET /2 HTTP/1.1\r\n"
5291 "Host: www.example.org\r\n"
5292 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205293 };
5294
5295 // The proxy responds to the connect with a 407, using a persistent
5296 // connection.
5297 MockRead data_reads1[] = {
5298 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5299
5300 MockRead("HTTP/1.1 200 OK\r\n"),
5301 MockRead("Content-Length: 1\r\n\r\n"),
5302 MockRead(SYNCHRONOUS, "1"),
5303
5304 MockRead("HTTP/1.1 200 OK\r\n"),
5305 MockRead("Content-Length: 2\r\n\r\n"),
5306 MockRead(SYNCHRONOUS, "22"),
5307 };
5308
Ryan Sleevib8d7ea02018-05-07 20:01:015309 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075310 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205311 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075312 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205313
5314 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585315 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195316 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205317
5318 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015319 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205320
5321 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015322 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205323
5324 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525325 ASSERT_TRUE(response1);
5326 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205327 EXPECT_EQ(1, response1->headers->GetContentLength());
5328
5329 LoadTimingInfo load_timing_info1;
5330 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5331 TestLoadTimingNotReusedWithPac(load_timing_info1,
5332 CONNECT_TIMING_HAS_SSL_TIMES);
5333
5334 trans1.reset();
5335
5336 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585337 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195338 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205339
5340 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015341 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205342
5343 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015344 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205345
5346 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525347 ASSERT_TRUE(response2);
5348 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205349 EXPECT_EQ(2, response2->headers->GetContentLength());
5350
5351 LoadTimingInfo load_timing_info2;
5352 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5353 TestLoadTimingReusedWithPac(load_timing_info2);
5354
5355 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5356
5357 trans2.reset();
5358 session->CloseAllConnections();
5359}
5360
[email protected]2df19bb2010-08-25 20:13:465361// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015362TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275363 HttpRequestInfo request;
5364 request.method = "GET";
bncce36dca22015-04-21 22:11:235365 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105366 request.traffic_annotation =
5367 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275368
[email protected]2df19bb2010-08-25 20:13:465369 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495370 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5371 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515372 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075373 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095374 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465375
[email protected]2df19bb2010-08-25 20:13:465376 // Since we have proxy, should use full url
5377 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235378 MockWrite(
5379 "GET http://www.example.org/ HTTP/1.1\r\n"
5380 "Host: www.example.org\r\n"
5381 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465382 };
5383
5384 MockRead data_reads1[] = {
5385 MockRead("HTTP/1.1 200 OK\r\n"),
5386 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5387 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065388 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465389 };
5390
Ryan Sleevib8d7ea02018-05-07 20:01:015391 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075392 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065393 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075394 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465395
[email protected]49639fa2011-12-20 23:22:415396 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465397
bnc691fda62016-08-12 00:43:165398 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505399
bnc691fda62016-08-12 00:43:165400 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015401 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465402
5403 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015404 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465405
[email protected]58e32bb2013-01-21 18:23:255406 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165407 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255408 TestLoadTimingNotReused(load_timing_info,
5409 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5410
bnc691fda62016-08-12 00:43:165411 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525412 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465413
tbansal2ecbbc72016-10-06 17:15:475414 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465415 EXPECT_TRUE(response->headers->IsKeepAlive());
5416 EXPECT_EQ(200, response->headers->response_code());
5417 EXPECT_EQ(100, response->headers->GetContentLength());
5418 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5419
5420 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525421 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465422}
5423
[email protected]7642b5ae2010-09-01 20:55:175424// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015425TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275426 HttpRequestInfo request;
5427 request.method = "GET";
bncce36dca22015-04-21 22:11:235428 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105429 request.traffic_annotation =
5430 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275431
[email protected]7642b5ae2010-09-01 20:55:175432 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495433 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5434 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515435 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075436 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095437 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175438
bncce36dca22015-04-21 22:11:235439 // fetch http://www.example.org/ via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135440 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455441 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415442 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175443
Ryan Hamilton0239aac2018-05-19 00:03:135444 spdy::SpdySerializedFrame resp(
5445 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5446 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175447 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415448 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175449 };
5450
Ryan Sleevib8d7ea02018-05-07 20:01:015451 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075452 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175453
[email protected]8ddf8322012-02-23 18:08:065454 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365455 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075456 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175457
[email protected]49639fa2011-12-20 23:22:415458 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175459
bnc691fda62016-08-12 00:43:165460 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505461
bnc691fda62016-08-12 00:43:165462 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015463 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175464
5465 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015466 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175467
[email protected]58e32bb2013-01-21 18:23:255468 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165469 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255470 TestLoadTimingNotReused(load_timing_info,
5471 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5472
bnc691fda62016-08-12 00:43:165473 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525474 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475475 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525476 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025477 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175478
5479 std::string response_data;
bnc691fda62016-08-12 00:43:165480 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235481 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175482}
5483
[email protected]1c173852014-06-19 12:51:505484// Verifies that a session which races and wins against the owning transaction
5485// (completing prior to host resolution), doesn't fail the transaction.
5486// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015487TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505488 HttpRequestInfo request;
5489 request.method = "GET";
bncce36dca22015-04-21 22:11:235490 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105491 request.traffic_annotation =
5492 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505493
5494 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495495 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5496 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515497 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505498 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095499 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505500
bncce36dca22015-04-21 22:11:235501 // Fetch http://www.example.org/ through the SPDY proxy.
Ryan Hamilton0239aac2018-05-19 00:03:135502 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455503 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415504 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505505
Raul Tambre94493c652019-03-11 17:18:355506 spdy::SpdySerializedFrame resp(
5507 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135508 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505509 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415510 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505511 };
5512
Ryan Sleevib8d7ea02018-05-07 20:01:015513 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]1c173852014-06-19 12:51:505514 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5515
5516 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365517 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505518 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5519
5520 TestCompletionCallback callback1;
5521
bnc691fda62016-08-12 00:43:165522 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505523
5524 // Stall the hostname resolution begun by the transaction.
[email protected]1c173852014-06-19 12:51:505525 session_deps_.host_resolver->set_ondemand_mode(true);
5526
bnc691fda62016-08-12 00:43:165527 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015528 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505529
5530 // Race a session to the proxy, which completes first.
5531 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045532 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:115533 PRIVACY_MODE_DISABLED,
5534 SpdySessionKey::IsProxySession::kTrue, SocketTag());
[email protected]1c173852014-06-19 12:51:505535 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525536 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505537
5538 // Unstall the resolution begun by the transaction.
5539 session_deps_.host_resolver->set_ondemand_mode(true);
5540 session_deps_.host_resolver->ResolveAllPending();
5541
5542 EXPECT_FALSE(callback1.have_result());
5543 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015544 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505545
bnc691fda62016-08-12 00:43:165546 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525547 ASSERT_TRUE(response);
5548 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025549 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505550
5551 std::string response_data;
bnc691fda62016-08-12 00:43:165552 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505553 EXPECT_EQ(kUploadData, response_data);
5554}
5555
[email protected]dc7bd1c52010-11-12 00:01:135556// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015557TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275558 HttpRequestInfo request;
5559 request.method = "GET";
bncce36dca22015-04-21 22:11:235560 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105561 request.traffic_annotation =
5562 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275563
[email protected]79cb5c12011-09-12 13:12:045564 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495565 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5566 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515567 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075568 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095569 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135570
[email protected]dc7bd1c52010-11-12 00:01:135571 // The first request will be a bare GET, the second request will be a
5572 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455573 spdy_util_.set_default_url(request.url);
Ryan Hamilton0239aac2018-05-19 00:03:135574 spdy::SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485575 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385576 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135577 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465578 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135579 };
Ryan Hamilton0239aac2018-05-19 00:03:135580 spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
Avi Drissman4365a4782018-12-28 19:26:245581 kExtraAuthorizationHeaders, base::size(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485582 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135583 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415584 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135585 };
5586
5587 // The first response is a 407 proxy authentication challenge, and the second
5588 // response will be a 200 response since the second request includes a valid
5589 // Authorization header.
5590 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465591 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135592 };
Ryan Hamilton0239aac2018-05-19 00:03:135593 spdy::SpdySerializedFrame resp_authentication(
5594 spdy_util_.ConstructSpdyReplyError(
5595 "407", kExtraAuthenticationHeaders,
Avi Drissman4365a4782018-12-28 19:26:245596 base::size(kExtraAuthenticationHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135597 spdy::SpdySerializedFrame body_authentication(
bncdf80d44fd2016-07-15 20:27:415598 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:135599 spdy::SpdySerializedFrame resp_data(
Raul Tambre94493c652019-03-11 17:18:355600 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:135601 spdy::SpdySerializedFrame body_data(
5602 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135603 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415604 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465605 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415606 CreateMockRead(resp_data, 4),
5607 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135608 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135609 };
5610
Ryan Sleevib8d7ea02018-05-07 20:01:015611 SequencedSocketData data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075612 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135613
[email protected]8ddf8322012-02-23 18:08:065614 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365615 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075616 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135617
[email protected]49639fa2011-12-20 23:22:415618 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135619
bnc691fda62016-08-12 00:43:165620 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135621
bnc691fda62016-08-12 00:43:165622 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015623 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135624
5625 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015626 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135627
bnc691fda62016-08-12 00:43:165628 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135629
wezca1070932016-05-26 20:30:525630 ASSERT_TRUE(response);
5631 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135632 EXPECT_EQ(407, response->headers->response_code());
5633 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435634 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135635
[email protected]49639fa2011-12-20 23:22:415636 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135637
bnc691fda62016-08-12 00:43:165638 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015639 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135640
5641 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015642 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135643
bnc691fda62016-08-12 00:43:165644 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135645
wezca1070932016-05-26 20:30:525646 ASSERT_TRUE(response_restart);
5647 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135648 EXPECT_EQ(200, response_restart->headers->response_code());
5649 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525650 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135651}
5652
[email protected]d9da5fe2010-10-13 22:37:165653// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015654TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275655 HttpRequestInfo request;
5656 request.method = "GET";
bncce36dca22015-04-21 22:11:235657 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105658 request.traffic_annotation =
5659 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275660
[email protected]d9da5fe2010-10-13 22:37:165661 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495662 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5663 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515664 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075665 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095666 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165667
bnc691fda62016-08-12 00:43:165668 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165669
bncce36dca22015-04-21 22:11:235670 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135671 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045672 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5673 HostPortPair("www.example.org", 443)));
bncce36dca22015-04-21 22:11:235674 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165675
bncce36dca22015-04-21 22:11:235676 const char get[] =
5677 "GET / HTTP/1.1\r\n"
5678 "Host: www.example.org\r\n"
5679 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135680 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195681 spdy_util_.ConstructSpdyDataFrame(1, get, false));
Ryan Hamilton0239aac2018-05-19 00:03:135682 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:355683 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165684 const char resp[] = "HTTP/1.1 200 OK\r\n"
5685 "Content-Length: 10\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135686 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195687 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:135688 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195689 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
Ryan Hamilton0239aac2018-05-19 00:03:135690 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415691 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045692
5693 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415694 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5695 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045696 };
5697
[email protected]d9da5fe2010-10-13 22:37:165698 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415699 CreateMockRead(conn_resp, 1, ASYNC),
5700 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5701 CreateMockRead(wrapped_body, 4, ASYNC),
5702 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135703 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165704 };
5705
Ryan Sleevib8d7ea02018-05-07 20:01:015706 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075707 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165708
[email protected]8ddf8322012-02-23 18:08:065709 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365710 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075711 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065712 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075713 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165714
[email protected]49639fa2011-12-20 23:22:415715 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165716
bnc691fda62016-08-12 00:43:165717 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165719
5720 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015721 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165722
[email protected]58e32bb2013-01-21 18:23:255723 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165724 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255725 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5726
bnc691fda62016-08-12 00:43:165727 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525728 ASSERT_TRUE(response);
5729 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165730 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5731
5732 std::string response_data;
bnc691fda62016-08-12 00:43:165733 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165734 EXPECT_EQ("1234567890", response_data);
5735}
5736
5737// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015738TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5739 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385740
[email protected]cb9bf6ca2011-01-28 13:15:275741 HttpRequestInfo request;
5742 request.method = "GET";
bncce36dca22015-04-21 22:11:235743 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105744 request.traffic_annotation =
5745 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275746
[email protected]d9da5fe2010-10-13 22:37:165747 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495748 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5749 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515750 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075751 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095752 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165753
bnc691fda62016-08-12 00:43:165754 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165755
bncce36dca22015-04-21 22:11:235756 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135757 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045758 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5759 HostPortPair("www.example.org", 443)));
bncce36dca22015-04-21 22:11:235760 // fetch https://www.example.org/ via SPDY
5761 const char kMyUrl[] = "https://www.example.org/";
Ryan Hamilton0239aac2018-05-19 00:03:135762 spdy::SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495763 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:135764 spdy::SpdySerializedFrame wrapped_get(
5765 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
5766 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:355767 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135768 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:355769 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135770 spdy::SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025771 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135772 spdy::SpdySerializedFrame body(
5773 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5774 spdy::SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025775 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135776 spdy::SpdySerializedFrame window_update_get_resp(
bncdf80d44fd2016-07-15 20:27:415777 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
Ryan Hamilton0239aac2018-05-19 00:03:135778 spdy::SpdySerializedFrame window_update_body(
bncdf80d44fd2016-07-15 20:27:415779 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045780
5781 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415782 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5783 CreateMockWrite(window_update_get_resp, 6),
5784 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045785 };
5786
[email protected]d9da5fe2010-10-13 22:37:165787 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415788 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095789 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415790 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5791 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135792 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165793 };
5794
Ryan Sleevib8d7ea02018-05-07 20:01:015795 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075796 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165797
[email protected]8ddf8322012-02-23 18:08:065798 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365799 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075800 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065801 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365802 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075803 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165804
[email protected]49639fa2011-12-20 23:22:415805 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165806
bnc691fda62016-08-12 00:43:165807 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015808 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165809
rch32320842015-05-16 15:57:095810 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555811 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095812 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595813 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165814 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015815 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165816
[email protected]58e32bb2013-01-21 18:23:255817 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165818 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255819 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5820
bnc691fda62016-08-12 00:43:165821 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525822 ASSERT_TRUE(response);
5823 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025824 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165825
5826 std::string response_data;
bnc691fda62016-08-12 00:43:165827 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235828 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165829}
5830
5831// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015832TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275833 HttpRequestInfo request;
5834 request.method = "GET";
bncce36dca22015-04-21 22:11:235835 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105836 request.traffic_annotation =
5837 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275838
[email protected]d9da5fe2010-10-13 22:37:165839 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495840 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5841 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515842 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075843 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095844 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165845
bnc691fda62016-08-12 00:43:165846 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165847
bncce36dca22015-04-21 22:11:235848 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135849 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045850 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5851 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135852 spdy::SpdySerializedFrame get(
5853 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165854
5855 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415856 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165857 };
5858
Ryan Hamilton0239aac2018-05-19 00:03:135859 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
5860 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165861 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415862 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165863 };
5864
Ryan Sleevib8d7ea02018-05-07 20:01:015865 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075866 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165867
[email protected]8ddf8322012-02-23 18:08:065868 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365869 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075870 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065871 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365872 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075873 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165874
[email protected]49639fa2011-12-20 23:22:415875 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165876
bnc691fda62016-08-12 00:43:165877 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015878 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165879
5880 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015881 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165882
ttuttle960fcbf2016-04-19 13:26:325883 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165884}
5885
Matt Menkecb2cd0982018-12-19 17:54:045886// Test the case where a proxied H2 session doesn't exist when an auth challenge
5887// is observed, but does exist by the time auth credentials are provided.
5888// Proxy-Connection: Close is used so that there's a second DNS lookup, which is
5889// what causes the existing H2 session to be noticed and reused.
5890TEST_F(HttpNetworkTransactionTest, ProxiedH2SessionAppearsDuringAuth) {
5891 ProxyConfig proxy_config;
5892 proxy_config.set_auto_detect(true);
5893 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
5894
5895 CapturingProxyResolver capturing_proxy_resolver;
5896 capturing_proxy_resolver.set_proxy_server(
5897 ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 70)));
5898 session_deps_.proxy_resolution_service =
5899 std::make_unique<ProxyResolutionService>(
5900 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
5901 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
5902 std::make_unique<CapturingProxyResolverFactory>(
5903 &capturing_proxy_resolver),
5904 nullptr);
5905
5906 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5907
5908 const char kMyUrl[] = "https://www.example.org/";
5909 spdy::SpdySerializedFrame get(spdy_util_.ConstructSpdyGet(kMyUrl, 1, LOWEST));
5910 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:355911 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menkecb2cd0982018-12-19 17:54:045912 spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
5913
5914 spdy_util_.UpdateWithStreamDestruction(1);
5915 spdy::SpdySerializedFrame get2(
5916 spdy_util_.ConstructSpdyGet(kMyUrl, 3, LOWEST));
5917 spdy::SpdySerializedFrame get_resp2(
Raul Tambre94493c652019-03-11 17:18:355918 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Matt Menkecb2cd0982018-12-19 17:54:045919 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
5920
5921 MockWrite auth_challenge_writes[] = {
5922 MockWrite(ASYNC, 0,
5923 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5924 "Host: www.example.org:443\r\n"
5925 "Proxy-Connection: keep-alive\r\n\r\n"),
5926 };
5927
5928 MockRead auth_challenge_reads[] = {
5929 MockRead(ASYNC, 1,
5930 "HTTP/1.1 407 Authentication Required\r\n"
5931 "Content-Length: 0\r\n"
5932 "Proxy-Connection: close\r\n"
5933 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
5934 };
5935
5936 MockWrite spdy_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"
5941 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5942 CreateMockWrite(get, 2),
5943 CreateMockWrite(get2, 5),
5944 };
5945
5946 MockRead spdy_reads[] = {
5947 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
5948 CreateMockRead(get_resp, 3, ASYNC),
5949 CreateMockRead(body, 4, ASYNC),
5950 CreateMockRead(get_resp2, 6, ASYNC),
5951 CreateMockRead(body2, 7, ASYNC),
5952
5953 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 8),
5954 };
5955
5956 SequencedSocketData auth_challenge1(auth_challenge_reads,
5957 auth_challenge_writes);
5958 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge1);
5959
5960 SequencedSocketData auth_challenge2(auth_challenge_reads,
5961 auth_challenge_writes);
5962 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge2);
5963
5964 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
5965 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5966
5967 SSLSocketDataProvider ssl(ASYNC, OK);
5968 ssl.next_proto = kProtoHTTP2;
5969 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5970
5971 TestCompletionCallback callback;
5972 std::string response_data;
5973
5974 // Run first request until an auth challenge is observed.
5975 HttpRequestInfo request1;
5976 request1.method = "GET";
5977 request1.url = GURL(kMyUrl);
5978 request1.traffic_annotation =
5979 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5980 HttpNetworkTransaction trans1(LOWEST, session.get());
5981 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
5982 EXPECT_THAT(callback.GetResult(rv), IsOk());
5983 const HttpResponseInfo* response = trans1.GetResponseInfo();
5984 ASSERT_TRUE(response);
5985 ASSERT_TRUE(response->headers);
5986 EXPECT_EQ(407, response->headers->response_code());
5987 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5988 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
5989
5990 // Run second request until an auth challenge is observed.
5991 HttpRequestInfo request2;
5992 request2.method = "GET";
5993 request2.url = GURL(kMyUrl);
5994 request2.traffic_annotation =
5995 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5996 HttpNetworkTransaction trans2(LOWEST, session.get());
5997 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
5998 EXPECT_THAT(callback.GetResult(rv), IsOk());
5999 response = trans2.GetResponseInfo();
6000 ASSERT_TRUE(response);
6001 ASSERT_TRUE(response->headers);
6002 EXPECT_EQ(407, response->headers->response_code());
6003 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6004 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6005
6006 // Now provide credentials for the first request, and wait for it to complete.
6007 rv = trans1.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6008 rv = callback.GetResult(rv);
6009 EXPECT_THAT(rv, IsOk());
6010 response = trans1.GetResponseInfo();
6011 ASSERT_TRUE(response);
6012 ASSERT_TRUE(response->headers);
6013 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6014 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6015 EXPECT_EQ(kUploadData, response_data);
6016
6017 // Now provide credentials for the second request. It should notice the
6018 // existing session, and reuse it.
6019 rv = trans2.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6020 EXPECT_THAT(callback.GetResult(rv), IsOk());
6021 response = trans2.GetResponseInfo();
6022 ASSERT_TRUE(response);
6023 ASSERT_TRUE(response->headers);
6024 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6025 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6026 EXPECT_EQ(kUploadData, response_data);
6027}
6028
[email protected]f6c63db52013-02-02 00:35:226029// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6030// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:016031TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226032 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
6033 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496034 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6035 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516036 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076037 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096038 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506039 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226040
6041 HttpRequestInfo request1;
6042 request1.method = "GET";
bncce36dca22015-04-21 22:11:236043 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226044 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106045 request1.traffic_annotation =
6046 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226047
6048 HttpRequestInfo request2;
6049 request2.method = "GET";
bncce36dca22015-04-21 22:11:236050 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226051 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106052 request2.traffic_annotation =
6053 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226054
bncce36dca22015-04-21 22:11:236055 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136056 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046057 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6058 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136059 spdy::SpdySerializedFrame conn_resp1(
Raul Tambre94493c652019-03-11 17:18:356060 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226061
bncce36dca22015-04-21 22:11:236062 // Fetch https://www.example.org/ via HTTP.
6063 const char get1[] =
6064 "GET / HTTP/1.1\r\n"
6065 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226066 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136067 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196068 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226069 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6070 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136071 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196072 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136073 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196074 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136075 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416076 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226077
bncce36dca22015-04-21 22:11:236078 // CONNECT to mail.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136079 spdy::SpdyHeaderBlock connect2_block;
6080 connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
6081 connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
6082 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
Matt Menke6e879bd2019-03-18 17:26:046083 3, std::move(connect2_block), HttpProxyConnectJob::kH2QuicTunnelPriority,
6084 false));
[email protected]601e03f12014-04-06 16:26:396085
Ryan Hamilton0239aac2018-05-19 00:03:136086 spdy::SpdySerializedFrame conn_resp2(
Raul Tambre94493c652019-03-11 17:18:356087 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
[email protected]f6c63db52013-02-02 00:35:226088
bncce36dca22015-04-21 22:11:236089 // Fetch https://mail.example.org/ via HTTP.
6090 const char get2[] =
6091 "GET / HTTP/1.1\r\n"
6092 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226093 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136094 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196095 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:226096 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6097 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136098 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196099 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136100 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196101 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:226102
6103 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416104 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6105 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:226106 };
6107
6108 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416109 CreateMockRead(conn_resp1, 1, ASYNC),
6110 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
6111 CreateMockRead(wrapped_body1, 4, ASYNC),
6112 CreateMockRead(conn_resp2, 6, ASYNC),
6113 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
6114 CreateMockRead(wrapped_body2, 9, ASYNC),
6115 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:226116 };
6117
Ryan Sleevib8d7ea02018-05-07 20:01:016118 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506119 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226120
6121 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366122 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506123 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226124 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506125 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226126 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506127 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:226128
6129 TestCompletionCallback callback;
6130
bnc691fda62016-08-12 00:43:166131 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206132 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016133 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226134
6135 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166136 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:226137 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6138
bnc691fda62016-08-12 00:43:166139 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526140 ASSERT_TRUE(response);
6141 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226142 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6143
6144 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446145 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
bnc691fda62016-08-12 00:43:166146 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506147 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226148
bnc691fda62016-08-12 00:43:166149 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206150 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016151 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226152
6153 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166154 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226155 // Even though the SPDY connection is reused, a new tunnelled connection has
6156 // to be created, so the socket's load timing looks like a fresh connection.
6157 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
6158
6159 // The requests should have different IDs, since they each are using their own
6160 // separate stream.
6161 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6162
bnc691fda62016-08-12 00:43:166163 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506164 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226165}
6166
6167// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6168// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:016169TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226170 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
6171 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496172 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6173 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516174 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076175 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096176 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506177 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226178
6179 HttpRequestInfo request1;
6180 request1.method = "GET";
bncce36dca22015-04-21 22:11:236181 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226182 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106183 request1.traffic_annotation =
6184 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226185
6186 HttpRequestInfo request2;
6187 request2.method = "GET";
bncce36dca22015-04-21 22:11:236188 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:226189 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106190 request2.traffic_annotation =
6191 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226192
bncce36dca22015-04-21 22:11:236193 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136194 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046195 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6196 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136197 spdy::SpdySerializedFrame conn_resp1(
Raul Tambre94493c652019-03-11 17:18:356198 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226199
bncce36dca22015-04-21 22:11:236200 // Fetch https://www.example.org/ via HTTP.
6201 const char get1[] =
6202 "GET / HTTP/1.1\r\n"
6203 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226204 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136205 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196206 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226207 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6208 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136209 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196210 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136211 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196212 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136213 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416214 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226215
bncce36dca22015-04-21 22:11:236216 // Fetch https://www.example.org/2 via HTTP.
6217 const char get2[] =
6218 "GET /2 HTTP/1.1\r\n"
6219 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226220 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136221 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196222 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:226223 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6224 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136225 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196226 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136227 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196228 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:226229
6230 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416231 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6232 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:226233 };
6234
6235 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416236 CreateMockRead(conn_resp1, 1, ASYNC),
6237 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:466238 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416239 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:466240 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416241 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:226242 };
6243
Ryan Sleevib8d7ea02018-05-07 20:01:016244 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506245 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226246
6247 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366248 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506249 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226250 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506251 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226252
6253 TestCompletionCallback callback;
6254
bnc87dcefc2017-05-25 12:47:586255 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196256 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206257 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016258 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226259
6260 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016261 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226262
6263 LoadTimingInfo load_timing_info;
6264 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6265 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6266
6267 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526268 ASSERT_TRUE(response);
6269 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226270 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6271
6272 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446273 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
[email protected]90499482013-06-01 00:39:506274 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226275 trans.reset();
6276
bnc87dcefc2017-05-25 12:47:586277 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:196278 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206279 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016280 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226281
[email protected]f6c63db52013-02-02 00:35:226282 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016283 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226284
6285 LoadTimingInfo load_timing_info2;
6286 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
6287 TestLoadTimingReused(load_timing_info2);
6288
6289 // The requests should have the same ID.
6290 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6291
[email protected]90499482013-06-01 00:39:506292 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226293}
6294
6295// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
6296// Proxy to different servers.
bncd16676a2016-07-20 16:23:016297TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:226298 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496299 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6300 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516301 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076302 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096303 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506304 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226305
6306 HttpRequestInfo request1;
6307 request1.method = "GET";
bncce36dca22015-04-21 22:11:236308 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226309 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106310 request1.traffic_annotation =
6311 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226312
6313 HttpRequestInfo request2;
6314 request2.method = "GET";
bncce36dca22015-04-21 22:11:236315 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226316 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:106317 request2.traffic_annotation =
6318 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226319
bncce36dca22015-04-21 22:11:236320 // http://www.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136321 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:236322 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136323 spdy::SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:156324 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136325 spdy::SpdySerializedFrame get_resp1(
Raul Tambre94493c652019-03-11 17:18:356326 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:136327 spdy::SpdySerializedFrame body1(
6328 spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:386329 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:226330
bncce36dca22015-04-21 22:11:236331 // http://mail.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136332 spdy::SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:236333 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136334 spdy::SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:156335 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136336 spdy::SpdySerializedFrame get_resp2(
Raul Tambre94493c652019-03-11 17:18:356337 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:136338 spdy::SpdySerializedFrame body2(
6339 spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:226340
6341 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416342 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:226343 };
6344
6345 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416346 CreateMockRead(get_resp1, 1, ASYNC),
6347 CreateMockRead(body1, 2, ASYNC),
6348 CreateMockRead(get_resp2, 4, ASYNC),
6349 CreateMockRead(body2, 5, ASYNC),
6350 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:226351 };
6352
Ryan Sleevib8d7ea02018-05-07 20:01:016353 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506354 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226355
6356 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366357 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506358 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226359
6360 TestCompletionCallback callback;
6361
bnc87dcefc2017-05-25 12:47:586362 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196363 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206364 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016365 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226366
6367 LoadTimingInfo load_timing_info;
6368 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6369 TestLoadTimingNotReused(load_timing_info,
6370 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6371
6372 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526373 ASSERT_TRUE(response);
6374 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:026375 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:226376
6377 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446378 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
mmenke11eb5152015-06-09 14:50:506379 rv = trans->Read(buf.get(), 256, callback.callback());
6380 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226381 // Delete the first request, so the second one can reuse the socket.
6382 trans.reset();
6383
bnc691fda62016-08-12 00:43:166384 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206385 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016386 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226387
6388 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166389 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226390 TestLoadTimingReused(load_timing_info2);
6391
6392 // The requests should have the same ID.
6393 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6394
bnc691fda62016-08-12 00:43:166395 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506396 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226397}
6398
Matt Menke2436b2f2018-12-11 18:07:116399// Test that an HTTP/2 CONNECT through an HTTPS Proxy to a HTTP/2 server and a
6400// direct (non-proxied) request to the proxy server are not pooled, as that
6401// would break socket pool isolation.
6402TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation1) {
6403 ProxyConfig proxy_config;
6404 proxy_config.set_auto_detect(true);
6405 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6406
6407 CapturingProxyResolver capturing_proxy_resolver;
6408 session_deps_.proxy_resolution_service =
6409 std::make_unique<ProxyResolutionService>(
6410 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6411 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6412 std::make_unique<CapturingProxyResolverFactory>(
6413 &capturing_proxy_resolver),
6414 nullptr);
6415
6416 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6417
6418 SpdyTestUtil spdy_util1;
6419 // CONNECT to www.example.org:443 via HTTP/2.
6420 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046421 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6422 HostPortPair("www.example.org", 443)));
Matt Menke2436b2f2018-12-11 18:07:116423 // fetch https://www.example.org/ via HTTP/2.
6424 const char kMyUrl[] = "https://www.example.org/";
6425 spdy::SpdySerializedFrame get(spdy_util1.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6426 spdy::SpdySerializedFrame wrapped_get(
6427 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6428 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:356429 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menke2436b2f2018-12-11 18:07:116430 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:356431 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menke2436b2f2018-12-11 18:07:116432 spdy::SpdySerializedFrame wrapped_get_resp(
6433 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6434 spdy::SpdySerializedFrame body(spdy_util1.ConstructSpdyDataFrame(1, true));
6435 spdy::SpdySerializedFrame wrapped_body(
6436 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6437 spdy::SpdySerializedFrame window_update_get_resp(
6438 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6439 spdy::SpdySerializedFrame window_update_body(
6440 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6441
6442 MockWrite spdy_writes1[] = {
6443 CreateMockWrite(connect, 0),
6444 CreateMockWrite(wrapped_get, 2),
6445 CreateMockWrite(window_update_get_resp, 6),
6446 CreateMockWrite(window_update_body, 7),
6447 };
6448
6449 MockRead spdy_reads1[] = {
6450 CreateMockRead(conn_resp, 1, ASYNC),
6451 MockRead(ASYNC, ERR_IO_PENDING, 3),
6452 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6453 CreateMockRead(wrapped_body, 5, ASYNC),
6454 MockRead(ASYNC, 0, 8),
6455 };
6456
6457 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6458 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6459
6460 // Fetch https://proxy:70/ via HTTP/2. Needs a new SpdyTestUtil, since it uses
6461 // a new pipe.
6462 SpdyTestUtil spdy_util2;
6463 spdy::SpdySerializedFrame req(
6464 spdy_util2.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6465 MockWrite spdy_writes2[] = {CreateMockWrite(req, 0)};
6466
6467 spdy::SpdySerializedFrame resp(
6468 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6469 spdy::SpdySerializedFrame data(spdy_util2.ConstructSpdyDataFrame(1, true));
6470 MockRead spdy_reads2[] = {
6471 CreateMockRead(resp, 1),
6472 CreateMockRead(data, 2),
6473 MockRead(ASYNC, 0, 3),
6474 };
6475 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6476 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6477
6478 SSLSocketDataProvider ssl(ASYNC, OK);
6479 ssl.next_proto = kProtoHTTP2;
6480 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6481 SSLSocketDataProvider ssl2(ASYNC, OK);
6482 ssl2.next_proto = kProtoHTTP2;
6483 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6484 SSLSocketDataProvider ssl3(ASYNC, OK);
6485 ssl3.next_proto = kProtoHTTP2;
6486 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6487
6488 TestCompletionCallback callback;
6489 std::string response_data;
6490
6491 // Make a request using proxy:70 as a HTTP/2 proxy.
6492 capturing_proxy_resolver.set_proxy_server(
6493 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6494 HttpRequestInfo request1;
6495 request1.method = "GET";
6496 request1.url = GURL("https://www.example.org/");
6497 request1.traffic_annotation =
6498 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6499
6500 HttpNetworkTransaction trans1(LOWEST, session.get());
6501 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
6502 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6503
6504 // Allow the SpdyProxyClientSocket's write callback to complete.
6505 base::RunLoop().RunUntilIdle();
6506 // Now allow the read of the response to complete.
6507 spdy_data1.Resume();
6508 rv = callback.WaitForResult();
6509 EXPECT_THAT(rv, IsOk());
6510
6511 const HttpResponseInfo* response = trans1.GetResponseInfo();
6512 ASSERT_TRUE(response);
6513 ASSERT_TRUE(response->headers);
6514 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6515
6516 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6517 EXPECT_EQ(kUploadData, response_data);
6518 RunUntilIdle();
6519
6520 // Make a direct HTTP/2 request to proxy:70.
6521 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6522 HttpRequestInfo request2;
6523 request2.method = "GET";
6524 request2.url = GURL("https://proxy:70/");
6525 request2.traffic_annotation =
6526 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6527 HttpNetworkTransaction trans2(LOWEST, session.get());
6528 EXPECT_THAT(callback.GetResult(trans2.Start(&request2, callback.callback(),
6529 NetLogWithSource())),
6530 IsOk());
6531 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6532}
6533
6534// Same as above, but reverse request order, since the code to check for an
6535// existing session is different for tunnels and direct connections.
6536TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation2) {
6537 // Configure against https proxy server "myproxy:80".
6538 ProxyConfig proxy_config;
6539 proxy_config.set_auto_detect(true);
6540 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6541
6542 CapturingProxyResolver capturing_proxy_resolver;
6543 session_deps_.proxy_resolution_service =
6544 std::make_unique<ProxyResolutionService>(
6545 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6546 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6547 std::make_unique<CapturingProxyResolverFactory>(
6548 &capturing_proxy_resolver),
6549 nullptr);
6550
6551 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6552 // Fetch https://proxy:70/ via HTTP/2.
6553 SpdyTestUtil spdy_util1;
6554 spdy::SpdySerializedFrame req(
6555 spdy_util1.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6556 MockWrite spdy_writes1[] = {CreateMockWrite(req, 0)};
6557
6558 spdy::SpdySerializedFrame resp(
6559 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
6560 spdy::SpdySerializedFrame data(spdy_util1.ConstructSpdyDataFrame(1, true));
6561 MockRead spdy_reads1[] = {
6562 CreateMockRead(resp, 1),
6563 CreateMockRead(data, 2),
6564 MockRead(ASYNC, 0, 3),
6565 };
6566 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6567 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6568
6569 SpdyTestUtil spdy_util2;
6570 // CONNECT to www.example.org:443 via HTTP/2.
6571 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046572 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6573 HostPortPair("www.example.org", 443)));
Matt Menke2436b2f2018-12-11 18:07:116574 // fetch https://www.example.org/ via HTTP/2.
6575 const char kMyUrl[] = "https://www.example.org/";
6576 spdy::SpdySerializedFrame get(spdy_util2.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6577 spdy::SpdySerializedFrame wrapped_get(
6578 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6579 spdy::SpdySerializedFrame conn_resp(
6580 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6581 spdy::SpdySerializedFrame get_resp(
6582 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6583 spdy::SpdySerializedFrame wrapped_get_resp(
6584 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6585 spdy::SpdySerializedFrame body(spdy_util2.ConstructSpdyDataFrame(1, true));
6586 spdy::SpdySerializedFrame wrapped_body(
6587 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6588 spdy::SpdySerializedFrame window_update_get_resp(
6589 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6590 spdy::SpdySerializedFrame window_update_body(
6591 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6592
6593 MockWrite spdy_writes2[] = {
6594 CreateMockWrite(connect, 0),
6595 CreateMockWrite(wrapped_get, 2),
6596 CreateMockWrite(window_update_get_resp, 6),
6597 CreateMockWrite(window_update_body, 7),
6598 };
6599
6600 MockRead spdy_reads2[] = {
6601 CreateMockRead(conn_resp, 1, ASYNC),
6602 MockRead(ASYNC, ERR_IO_PENDING, 3),
6603 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6604 CreateMockRead(wrapped_body, 5, ASYNC),
6605 MockRead(ASYNC, 0, 8),
6606 };
6607
6608 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6609 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6610
6611 SSLSocketDataProvider ssl(ASYNC, OK);
6612 ssl.next_proto = kProtoHTTP2;
6613 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6614 SSLSocketDataProvider ssl2(ASYNC, OK);
6615 ssl2.next_proto = kProtoHTTP2;
6616 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6617 SSLSocketDataProvider ssl3(ASYNC, OK);
6618 ssl3.next_proto = kProtoHTTP2;
6619 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6620
6621 TestCompletionCallback callback;
6622 std::string response_data;
6623
6624 // Make a direct HTTP/2 request to proxy:70.
6625 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6626 HttpRequestInfo request1;
6627 request1.method = "GET";
6628 request1.url = GURL("https://proxy:70/");
6629 request1.traffic_annotation =
6630 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6631 HttpNetworkTransaction trans1(LOWEST, session.get());
6632 EXPECT_THAT(callback.GetResult(trans1.Start(&request1, callback.callback(),
6633 NetLogWithSource())),
6634 IsOk());
6635 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6636 RunUntilIdle();
6637
6638 // Make a request using proxy:70 as a HTTP/2 proxy.
6639 capturing_proxy_resolver.set_proxy_server(
6640 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6641 HttpRequestInfo request2;
6642 request2.method = "GET";
6643 request2.url = GURL("https://www.example.org/");
6644 request2.traffic_annotation =
6645 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6646
6647 HttpNetworkTransaction trans2(LOWEST, session.get());
6648 int rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6649 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6650
6651 // Allow the SpdyProxyClientSocket's write callback to complete.
6652 base::RunLoop().RunUntilIdle();
6653 // Now allow the read of the response to complete.
6654 spdy_data2.Resume();
6655 rv = callback.WaitForResult();
6656 EXPECT_THAT(rv, IsOk());
6657
6658 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
6659 ASSERT_TRUE(response2);
6660 ASSERT_TRUE(response2->headers);
6661 EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
6662
6663 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6664 EXPECT_EQ(kUploadData, response_data);
6665}
6666
[email protected]2df19bb2010-08-25 20:13:466667// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:016668TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:466669 HttpRequestInfo request;
6670 request.method = "GET";
bncce36dca22015-04-21 22:11:236671 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466672 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296673 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:106674 request.traffic_annotation =
6675 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:466676
[email protected]79cb5c12011-09-12 13:12:046677 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496678 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6679 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516680 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076681 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096682 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276683
[email protected]2df19bb2010-08-25 20:13:466684 // Since we have proxy, should use full url
6685 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:166686 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6687 "Host: www.example.org\r\n"
6688 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466689
bnc691fda62016-08-12 00:43:166690 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:236691 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:166692 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6693 "Host: www.example.org\r\n"
6694 "Proxy-Connection: keep-alive\r\n"
6695 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466696 };
6697
6698 // The proxy responds to the GET with a 407, using a persistent
6699 // connection.
6700 MockRead data_reads1[] = {
6701 // No credentials.
6702 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6703 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6704 MockRead("Proxy-Connection: keep-alive\r\n"),
6705 MockRead("Content-Length: 0\r\n\r\n"),
6706
6707 MockRead("HTTP/1.1 200 OK\r\n"),
6708 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6709 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066710 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466711 };
6712
Ryan Sleevib8d7ea02018-05-07 20:01:016713 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:076714 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:066715 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076716 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466717
[email protected]49639fa2011-12-20 23:22:416718 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:466719
bnc691fda62016-08-12 00:43:166720 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506721
bnc691fda62016-08-12 00:43:166722 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:016723 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466724
6725 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016726 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466727
[email protected]58e32bb2013-01-21 18:23:256728 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166729 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256730 TestLoadTimingNotReused(load_timing_info,
6731 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6732
bnc691fda62016-08-12 00:43:166733 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526734 ASSERT_TRUE(response);
6735 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:466736 EXPECT_EQ(407, response->headers->response_code());
6737 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:436738 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:466739
[email protected]49639fa2011-12-20 23:22:416740 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:466741
bnc691fda62016-08-12 00:43:166742 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016743 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466744
6745 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016746 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466747
[email protected]58e32bb2013-01-21 18:23:256748 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:166749 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256750 // Retrying with HTTP AUTH is considered to be reusing a socket.
6751 TestLoadTimingReused(load_timing_info);
6752
bnc691fda62016-08-12 00:43:166753 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526754 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:466755
6756 EXPECT_TRUE(response->headers->IsKeepAlive());
6757 EXPECT_EQ(200, response->headers->response_code());
6758 EXPECT_EQ(100, response->headers->GetContentLength());
6759 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6760
6761 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:526762 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:466763}
6764
[email protected]23e482282013-06-14 16:08:026765void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086766 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426767 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086768 request.method = "GET";
bncce36dca22015-04-21 22:11:236769 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106770 request.traffic_annotation =
6771 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086772
[email protected]cb9bf6ca2011-01-28 13:15:276773 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496774 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6775 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096776 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276777
[email protected]c744cf22009-02-27 07:28:086778 // Since we have proxy, should try to establish tunnel.
6779 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176780 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6781 "Host: www.example.org:443\r\n"
6782 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086783 };
6784
6785 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236786 status, MockRead("Content-Length: 10\r\n\r\n"),
6787 // No response body because the test stops reading here.
6788 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086789 };
6790
Ryan Sleevib8d7ea02018-05-07 20:01:016791 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:076792 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086793
[email protected]49639fa2011-12-20 23:22:416794 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086795
bnc691fda62016-08-12 00:43:166796 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506797
tfarina42834112016-09-22 13:38:206798 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086800
6801 rv = callback.WaitForResult();
6802 EXPECT_EQ(expected_status, rv);
6803}
6804
[email protected]23e482282013-06-14 16:08:026805void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236806 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086807 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426808 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086809}
6810
bncd16676a2016-07-20 16:23:016811TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086812 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6813}
6814
bncd16676a2016-07-20 16:23:016815TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086816 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6817}
6818
bncd16676a2016-07-20 16:23:016819TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086820 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6821}
6822
bncd16676a2016-07-20 16:23:016823TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086824 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6825}
6826
bncd16676a2016-07-20 16:23:016827TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086828 ConnectStatusHelper(
6829 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6830}
6831
bncd16676a2016-07-20 16:23:016832TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086833 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6834}
6835
bncd16676a2016-07-20 16:23:016836TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086837 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6838}
6839
bncd16676a2016-07-20 16:23:016840TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086841 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6842}
6843
bncd16676a2016-07-20 16:23:016844TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086845 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6846}
6847
bncd16676a2016-07-20 16:23:016848TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086849 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6850}
6851
bncd16676a2016-07-20 16:23:016852TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086853 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6854}
6855
bncd16676a2016-07-20 16:23:016856TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086857 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6858}
6859
bncd16676a2016-07-20 16:23:016860TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086861 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6862}
6863
bncd16676a2016-07-20 16:23:016864TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086865 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6866}
6867
bncd16676a2016-07-20 16:23:016868TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086869 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6870}
6871
bncd16676a2016-07-20 16:23:016872TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086873 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6874}
6875
bncd16676a2016-07-20 16:23:016876TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376877 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6878}
6879
bncd16676a2016-07-20 16:23:016880TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086881 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6882}
6883
bncd16676a2016-07-20 16:23:016884TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086885 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6886}
6887
bncd16676a2016-07-20 16:23:016888TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086889 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6890}
6891
bncd16676a2016-07-20 16:23:016892TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086893 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6894}
6895
bncd16676a2016-07-20 16:23:016896TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086897 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6898}
6899
bncd16676a2016-07-20 16:23:016900TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086901 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6902}
6903
bncd16676a2016-07-20 16:23:016904TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086905 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6906}
6907
bncd16676a2016-07-20 16:23:016908TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086909 ConnectStatusHelperWithExpectedStatus(
6910 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546911 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086912}
6913
bncd16676a2016-07-20 16:23:016914TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086915 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6916}
6917
bncd16676a2016-07-20 16:23:016918TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086919 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6920}
6921
bncd16676a2016-07-20 16:23:016922TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086923 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6924}
6925
bncd16676a2016-07-20 16:23:016926TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086927 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6928}
6929
bncd16676a2016-07-20 16:23:016930TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086931 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6932}
6933
bncd16676a2016-07-20 16:23:016934TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086935 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6936}
6937
bncd16676a2016-07-20 16:23:016938TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086939 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6940}
6941
bncd16676a2016-07-20 16:23:016942TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086943 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6944}
6945
bncd16676a2016-07-20 16:23:016946TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086947 ConnectStatusHelper(
6948 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6949}
6950
bncd16676a2016-07-20 16:23:016951TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086952 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6953}
6954
bncd16676a2016-07-20 16:23:016955TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086956 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6957}
6958
bncd16676a2016-07-20 16:23:016959TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086960 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6961}
6962
bncd16676a2016-07-20 16:23:016963TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086964 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6965}
6966
bncd16676a2016-07-20 16:23:016967TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086968 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6969}
6970
bncd16676a2016-07-20 16:23:016971TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086972 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6973}
6974
bncd16676a2016-07-20 16:23:016975TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086976 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6977}
6978
[email protected]038e9a32008-10-08 22:40:166979// Test the flow when both the proxy server AND origin server require
6980// authentication. Again, this uses basic auth for both since that is
6981// the simplest to mock.
bncd16676a2016-07-20 16:23:016982TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276983 HttpRequestInfo request;
6984 request.method = "GET";
bncce36dca22015-04-21 22:11:236985 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106986 request.traffic_annotation =
6987 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276988
[email protected]038e9a32008-10-08 22:40:166989 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496990 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6991 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096992 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076993
bnc691fda62016-08-12 00:43:166994 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166995
[email protected]f9ee6b52008-11-08 06:46:236996 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236997 MockWrite(
6998 "GET http://www.example.org/ HTTP/1.1\r\n"
6999 "Host: www.example.org\r\n"
7000 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237001 };
7002
[email protected]038e9a32008-10-08 22:40:167003 MockRead data_reads1[] = {
7004 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
7005 // Give a couple authenticate options (only the middle one is actually
7006 // supported).
[email protected]22927ad2009-09-21 19:56:197007 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:167008 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7009 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
7010 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7011 // Large content-length -- won't matter, as connection will be reset.
7012 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067013 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:167014 };
7015
bnc691fda62016-08-12 00:43:167016 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:167017 // request we should be issuing -- the final header line contains the
7018 // proxy's credentials.
7019 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237020 MockWrite(
7021 "GET http://www.example.org/ HTTP/1.1\r\n"
7022 "Host: www.example.org\r\n"
7023 "Proxy-Connection: keep-alive\r\n"
7024 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167025 };
7026
7027 // Now the proxy server lets the request pass through to origin server.
7028 // The origin server responds with a 401.
7029 MockRead data_reads2[] = {
7030 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7031 // Note: We are using the same realm-name as the proxy server. This is
7032 // completely valid, as realms are unique across hosts.
7033 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7034 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7035 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067036 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:167037 };
7038
bnc691fda62016-08-12 00:43:167039 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:167040 // the credentials for both the proxy and origin server.
7041 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237042 MockWrite(
7043 "GET http://www.example.org/ HTTP/1.1\r\n"
7044 "Host: www.example.org\r\n"
7045 "Proxy-Connection: keep-alive\r\n"
7046 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
7047 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167048 };
7049
7050 // Lastly we get the desired content.
7051 MockRead data_reads3[] = {
7052 MockRead("HTTP/1.0 200 OK\r\n"),
7053 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7054 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067055 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:167056 };
7057
Ryan Sleevib8d7ea02018-05-07 20:01:017058 StaticSocketDataProvider data1(data_reads1, data_writes1);
7059 StaticSocketDataProvider data2(data_reads2, data_writes2);
7060 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077061 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7062 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7063 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:167064
[email protected]49639fa2011-12-20 23:22:417065 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:167066
tfarina42834112016-09-22 13:38:207067 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017068 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167069
7070 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017071 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167072
bnc691fda62016-08-12 00:43:167073 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527074 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047075 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167076
[email protected]49639fa2011-12-20 23:22:417077 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:167078
bnc691fda62016-08-12 00:43:167079 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:017080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167081
7082 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017083 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167084
bnc691fda62016-08-12 00:43:167085 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527086 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047087 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167088
[email protected]49639fa2011-12-20 23:22:417089 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:167090
bnc691fda62016-08-12 00:43:167091 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7092 callback3.callback());
robpercival214763f2016-07-01 23:27:017093 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167094
7095 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017096 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167097
bnc691fda62016-08-12 00:43:167098 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527099 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:167100 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:167101}
[email protected]4ddaf2502008-10-23 18:26:197102
[email protected]ea9dc9a2009-09-05 00:43:327103// For the NTLM implementation using SSPI, we skip the NTLM tests since we
7104// can't hook into its internals to cause it to generate predictable NTLM
7105// authorization headers.
7106#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377107// The NTLM authentication unit tests are based on known test data from the
7108// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
7109// flow rather than the implementation of the NTLM protocol. See net/ntlm
7110// for the implementation and testing of the protocol.
7111//
7112// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:297113
7114// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557115TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:427116 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:247117 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557118 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:107119 request.traffic_annotation =
7120 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547121
7122 // Ensure load is not disrupted by flags which suppress behaviour specific
7123 // to other auth schemes.
7124 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:247125
Zentaro Kavanagh6ccee512017-09-28 18:34:097126 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7127 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097128 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277129
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377130 // Generate the NTLM messages based on known test data.
7131 std::string negotiate_msg;
7132 std::string challenge_msg;
7133 std::string authenticate_msg;
7134 base::Base64Encode(
7135 base::StringPiece(
7136 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247137 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377138 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557139 base::Base64Encode(
7140 base::StringPiece(
7141 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247142 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557143 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377144 base::Base64Encode(
7145 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097146 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557147 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247148 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557149 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377150 &authenticate_msg);
7151
[email protected]3f918782009-02-28 01:29:247152 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557153 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7154 "Host: server\r\n"
7155 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247156 };
7157
7158 MockRead data_reads1[] = {
7159 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047160 // Negotiate and NTLM are often requested together. However, we only want
7161 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7162 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:247163 MockRead("WWW-Authenticate: NTLM\r\n"),
7164 MockRead("Connection: close\r\n"),
7165 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367166 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247167 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:247168 };
7169
7170 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167171 // After restarting with a null identity, this is the
7172 // request we should be issuing -- the final header line contains a Type
7173 // 1 message.
7174 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557175 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167176 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377177 "Authorization: NTLM "),
7178 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247179
bnc691fda62016-08-12 00:43:167180 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377181 // (using correct credentials). The second request continues on the
7182 // same connection.
bnc691fda62016-08-12 00:43:167183 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557184 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167185 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377186 "Authorization: NTLM "),
7187 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247188 };
7189
7190 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:027191 // The origin server responds with a Type 2 message.
7192 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377193 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7194 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027195 MockRead("Content-Type: text/html\r\n\r\n"),
7196 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:247197
Bence Béky1e4ef192017-09-18 19:58:027198 // Lastly we get the desired content.
7199 MockRead("HTTP/1.1 200 OK\r\n"),
7200 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7201 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:247202 };
7203
Ryan Sleevib8d7ea02018-05-07 20:01:017204 StaticSocketDataProvider data1(data_reads1, data_writes1);
7205 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077206 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7207 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:247208
Bence Béky83eb3512017-09-05 12:56:097209 SSLSocketDataProvider ssl1(ASYNC, OK);
7210 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7211 SSLSocketDataProvider ssl2(ASYNC, OK);
7212 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7213
[email protected]49639fa2011-12-20 23:22:417214 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:247215
bnc691fda62016-08-12 00:43:167216 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507217
tfarina42834112016-09-22 13:38:207218 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017219 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247220
7221 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017222 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247223
bnc691fda62016-08-12 00:43:167224 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227225
bnc691fda62016-08-12 00:43:167226 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527227 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047228 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:247229
[email protected]49639fa2011-12-20 23:22:417230 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:257231
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377232 rv = trans.RestartWithAuth(
7233 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7234 callback2.callback());
robpercival214763f2016-07-01 23:27:017235 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257236
7237 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017238 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257239
bnc691fda62016-08-12 00:43:167240 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257241
bnc691fda62016-08-12 00:43:167242 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527243 ASSERT_TRUE(response);
7244 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:257245
[email protected]49639fa2011-12-20 23:22:417246 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:247247
bnc691fda62016-08-12 00:43:167248 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017249 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247250
[email protected]0757e7702009-03-27 04:00:227251 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017252 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247253
bnc691fda62016-08-12 00:43:167254 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527255 ASSERT_TRUE(response);
7256 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027257 EXPECT_EQ(14, response->headers->GetContentLength());
7258
7259 std::string response_data;
7260 rv = ReadTransaction(&trans, &response_data);
7261 EXPECT_THAT(rv, IsOk());
7262 EXPECT_EQ("Please Login\r\n", response_data);
7263
7264 EXPECT_TRUE(data1.AllReadDataConsumed());
7265 EXPECT_TRUE(data1.AllWriteDataConsumed());
7266 EXPECT_TRUE(data2.AllReadDataConsumed());
7267 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:247268}
7269
[email protected]385a4672009-03-11 22:21:297270// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557271TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:427272 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:297273 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557274 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:107275 request.traffic_annotation =
7276 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:297277
Zentaro Kavanagh6ccee512017-09-28 18:34:097278 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7279 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097280 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277281
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377282 // Generate the NTLM messages based on known test data.
7283 std::string negotiate_msg;
7284 std::string challenge_msg;
7285 std::string authenticate_msg;
7286 base::Base64Encode(
7287 base::StringPiece(
7288 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247289 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377290 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557291 base::Base64Encode(
7292 base::StringPiece(
7293 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247294 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557295 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377296 base::Base64Encode(
7297 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097298 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557299 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247300 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557301 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377302 &authenticate_msg);
7303
7304 // The authenticate message when |kWrongPassword| is sent.
7305 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557306 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
7307 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
7308 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
7309 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
7310 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
7311 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377312
Zentaro Kavanagh1890a3d2018-01-29 19:52:557313 // Sanity check that it's the same length as the correct authenticate message
7314 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377315 ASSERT_EQ(authenticate_msg.length(),
7316 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:557317 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377318
[email protected]385a4672009-03-11 22:21:297319 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557320 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7321 "Host: server\r\n"
7322 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297323 };
7324
7325 MockRead data_reads1[] = {
7326 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047327 // Negotiate and NTLM are often requested together. However, we only want
7328 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7329 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:297330 MockRead("WWW-Authenticate: NTLM\r\n"),
7331 MockRead("Connection: close\r\n"),
7332 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367333 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297334 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297335 };
7336
7337 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167338 // After restarting with a null identity, this is the
7339 // request we should be issuing -- the final header line contains a Type
7340 // 1 message.
7341 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557342 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167343 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377344 "Authorization: NTLM "),
7345 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297346
bnc691fda62016-08-12 00:43:167347 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377348 // (using incorrect credentials). The second request continues on the
7349 // same connection.
bnc691fda62016-08-12 00:43:167350 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557351 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167352 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377353 "Authorization: NTLM "),
7354 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297355 };
7356
7357 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377358 // The origin server responds with a Type 2 message.
7359 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7360 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7361 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
7362 MockRead("Content-Type: text/html\r\n\r\n"),
7363 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297364
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377365 // Wrong password.
7366 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7367 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
7368 MockRead("Content-Length: 42\r\n"),
7369 MockRead("Content-Type: text/html\r\n\r\n"),
7370 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297371 };
7372
7373 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:167374 // After restarting with a null identity, this is the
7375 // request we should be issuing -- the final header line contains a Type
7376 // 1 message.
7377 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557378 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167379 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377380 "Authorization: NTLM "),
7381 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297382
bnc691fda62016-08-12 00:43:167383 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7384 // (the credentials for the origin server). The second request continues
7385 // on the same connection.
7386 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557387 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167388 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377389 "Authorization: NTLM "),
7390 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297391 };
7392
7393 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:027394 // The origin server responds with a Type 2 message.
7395 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377396 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7397 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027398 MockRead("Content-Type: text/html\r\n\r\n"),
7399 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297400
Bence Béky1e4ef192017-09-18 19:58:027401 // Lastly we get the desired content.
7402 MockRead("HTTP/1.1 200 OK\r\n"),
7403 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7404 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:297405 };
7406
Ryan Sleevib8d7ea02018-05-07 20:01:017407 StaticSocketDataProvider data1(data_reads1, data_writes1);
7408 StaticSocketDataProvider data2(data_reads2, data_writes2);
7409 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077410 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7411 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7412 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:297413
Bence Béky83eb3512017-09-05 12:56:097414 SSLSocketDataProvider ssl1(ASYNC, OK);
7415 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7416 SSLSocketDataProvider ssl2(ASYNC, OK);
7417 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7418 SSLSocketDataProvider ssl3(ASYNC, OK);
7419 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
7420
[email protected]49639fa2011-12-20 23:22:417421 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:297422
bnc691fda62016-08-12 00:43:167423 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507424
tfarina42834112016-09-22 13:38:207425 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017426 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297427
7428 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017429 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297430
bnc691fda62016-08-12 00:43:167431 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:297432
bnc691fda62016-08-12 00:43:167433 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527434 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047435 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:297436
[email protected]49639fa2011-12-20 23:22:417437 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:297438
[email protected]0757e7702009-03-27 04:00:227439 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377440 rv = trans.RestartWithAuth(
7441 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
7442 callback2.callback());
robpercival214763f2016-07-01 23:27:017443 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297444
[email protected]10af5fe72011-01-31 16:17:257445 rv = callback2.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_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417449 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167450 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017451 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257452 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017453 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167454 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227455
bnc691fda62016-08-12 00:43:167456 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527457 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047458 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:227459
[email protected]49639fa2011-12-20 23:22:417460 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:227461
7462 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377463 rv = trans.RestartWithAuth(
7464 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7465 callback4.callback());
robpercival214763f2016-07-01 23:27:017466 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257467
7468 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:017469 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257470
bnc691fda62016-08-12 00:43:167471 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257472
[email protected]49639fa2011-12-20 23:22:417473 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:257474
7475 // One more roundtrip
bnc691fda62016-08-12 00:43:167476 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:017477 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227478
7479 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:017480 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:227481
bnc691fda62016-08-12 00:43:167482 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527483 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027484 EXPECT_EQ(14, response->headers->GetContentLength());
7485
7486 std::string response_data;
7487 rv = ReadTransaction(&trans, &response_data);
7488 EXPECT_THAT(rv, IsOk());
7489 EXPECT_EQ("Please Login\r\n", response_data);
7490
7491 EXPECT_TRUE(data1.AllReadDataConsumed());
7492 EXPECT_TRUE(data1.AllWriteDataConsumed());
7493 EXPECT_TRUE(data2.AllReadDataConsumed());
7494 EXPECT_TRUE(data2.AllWriteDataConsumed());
7495 EXPECT_TRUE(data3.AllReadDataConsumed());
7496 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:297497}
Bence Béky83eb3512017-09-05 12:56:097498
Bence Béky3238f2e12017-09-22 22:44:497499// Server requests NTLM authentication, which is not supported over HTTP/2.
7500// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:097501TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:097502 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7503 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:097504
Zentaro Kavanagh1890a3d2018-01-29 19:52:557505 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:097506
7507 HttpRequestInfo request;
7508 request.method = "GET";
7509 request.url = GURL(kUrl);
Ramin Halavatib5e433e2018-02-07 07:41:107510 request.traffic_annotation =
7511 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:097512
7513 // First request without credentials.
Ryan Hamilton0239aac2018-05-19 00:03:137514 spdy::SpdyHeaderBlock request_headers0(
7515 spdy_util_.ConstructGetHeaderBlock(kUrl));
7516 spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
Bence Béky83eb3512017-09-05 12:56:097517 1, std::move(request_headers0), LOWEST, true));
7518
Ryan Hamilton0239aac2018-05-19 00:03:137519 spdy::SpdyHeaderBlock response_headers0;
7520 response_headers0[spdy::kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:097521 response_headers0["www-authenticate"] = "NTLM";
Ryan Hamilton0239aac2018-05-19 00:03:137522 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Béky83eb3512017-09-05 12:56:097523 1, std::move(response_headers0), true));
7524
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377525 // Stream 1 is closed.
7526 spdy_util_.UpdateWithStreamDestruction(1);
7527
7528 // Generate the NTLM messages based on known test data.
7529 std::string negotiate_msg;
7530 std::string challenge_msg;
7531 std::string authenticate_msg;
7532 base::Base64Encode(
7533 base::StringPiece(
7534 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247535 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377536 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557537 base::Base64Encode(
7538 base::StringPiece(
7539 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247540 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557541 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377542 base::Base64Encode(
7543 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097544 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557545 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247546 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557547 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377548 &authenticate_msg);
7549
7550 // Retry with authorization header.
Ryan Hamilton0239aac2018-05-19 00:03:137551 spdy::SpdyHeaderBlock request_headers1(
7552 spdy_util_.ConstructGetHeaderBlock(kUrl));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377553 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
Ryan Hamilton0239aac2018-05-19 00:03:137554 spdy::SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377555 3, std::move(request_headers1), LOWEST, true));
7556
Ryan Hamilton0239aac2018-05-19 00:03:137557 spdy::SpdySerializedFrame rst(
7558 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377559
Bence Béky3238f2e12017-09-22 22:44:497560 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
7561 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:097562
7563 // Retry yet again using HTTP/1.1.
7564 MockWrite writes1[] = {
7565 // After restarting with a null identity, this is the
7566 // request we should be issuing -- the final header line contains a Type
7567 // 1 message.
7568 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557569 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097570 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377571 "Authorization: NTLM "),
7572 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097573
7574 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7575 // (the credentials for the origin server). The second request continues
7576 // on the same connection.
7577 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557578 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097579 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377580 "Authorization: NTLM "),
7581 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097582 };
7583
7584 MockRead reads1[] = {
7585 // The origin server responds with a Type 2 message.
7586 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377587 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7588 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:097589 MockRead("Content-Type: text/html\r\n\r\n"),
7590 MockRead("You are not authorized to view this page\r\n"),
7591
7592 // Lastly we get the desired content.
7593 MockRead("HTTP/1.1 200 OK\r\n"),
7594 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027595 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:097596 };
Ryan Sleevib8d7ea02018-05-07 20:01:017597 SequencedSocketData data0(reads0, writes0);
7598 StaticSocketDataProvider data1(reads1, writes1);
Bence Béky83eb3512017-09-05 12:56:097599 session_deps_.socket_factory->AddSocketDataProvider(&data0);
7600 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7601
7602 SSLSocketDataProvider ssl0(ASYNC, OK);
7603 ssl0.next_proto = kProtoHTTP2;
7604 SSLSocketDataProvider ssl1(ASYNC, OK);
7605 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
7606 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7607
7608 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7609 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7610
7611 TestCompletionCallback callback1;
7612 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
7613 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7614
7615 rv = callback1.WaitForResult();
7616 EXPECT_THAT(rv, IsOk());
7617
7618 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7619
7620 const HttpResponseInfo* response = trans.GetResponseInfo();
7621 ASSERT_TRUE(response);
7622 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
7623
7624 TestCompletionCallback callback2;
7625
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377626 rv = trans.RestartWithAuth(
7627 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7628 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:097629 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7630
7631 rv = callback2.WaitForResult();
7632 EXPECT_THAT(rv, IsOk());
7633
7634 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7635
7636 response = trans.GetResponseInfo();
7637 ASSERT_TRUE(response);
7638 EXPECT_FALSE(response->auth_challenge);
7639
7640 TestCompletionCallback callback3;
7641
7642 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
7643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7644
7645 rv = callback3.WaitForResult();
7646 EXPECT_THAT(rv, IsOk());
7647
7648 response = trans.GetResponseInfo();
7649 ASSERT_TRUE(response);
7650 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027651 EXPECT_EQ(14, response->headers->GetContentLength());
7652
7653 std::string response_data;
7654 rv = ReadTransaction(&trans, &response_data);
7655 EXPECT_THAT(rv, IsOk());
7656 EXPECT_EQ("Please Login\r\n", response_data);
7657
7658 EXPECT_TRUE(data0.AllReadDataConsumed());
7659 EXPECT_TRUE(data0.AllWriteDataConsumed());
7660 EXPECT_TRUE(data1.AllReadDataConsumed());
7661 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:097662}
David Benjamin5cb91132018-04-06 05:54:497663
7664// Test that, if we have an NTLM proxy and the origin resets the connection, we
7665// do no retry forever checking for TLS version interference. This is a
7666// regression test for https://crbug.com/823387.
7667TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
7668 // The NTLM test data expects the proxy to be named 'server'. The origin is
7669 // https://origin/.
7670 session_deps_.proxy_resolution_service =
7671 ProxyResolutionService::CreateFixedFromPacResult(
7672 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
7673
7674 SSLConfig config;
David Benjamin5cb91132018-04-06 05:54:497675 session_deps_.ssl_config_service =
Ryan Sleevib8449e02018-07-15 04:31:077676 std::make_unique<TestSSLConfigService>(config);
David Benjamin5cb91132018-04-06 05:54:497677
7678 HttpRequestInfo request;
7679 request.method = "GET";
7680 request.url = GURL("https://origin/");
7681 request.traffic_annotation =
7682 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7683
7684 // Ensure load is not disrupted by flags which suppress behaviour specific
7685 // to other auth schemes.
7686 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7687
7688 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7689 MockGetMSTime, MockGenerateRandom, MockGetHostName);
7690 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7691
7692 // Generate the NTLM messages based on known test data.
7693 std::string negotiate_msg;
7694 std::string challenge_msg;
7695 std::string authenticate_msg;
7696 base::Base64Encode(
7697 base::StringPiece(
7698 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247699 base::size(ntlm::test::kExpectedNegotiateMsg)),
David Benjamin5cb91132018-04-06 05:54:497700 &negotiate_msg);
7701 base::Base64Encode(
7702 base::StringPiece(
7703 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247704 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
David Benjamin5cb91132018-04-06 05:54:497705 &challenge_msg);
7706 base::Base64Encode(
7707 base::StringPiece(
7708 reinterpret_cast<const char*>(
7709 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247710 base::size(
David Benjamin5cb91132018-04-06 05:54:497711 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
7712 &authenticate_msg);
7713
7714 MockWrite data_writes[] = {
7715 // The initial CONNECT request.
7716 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7717 "Host: origin:443\r\n"
7718 "Proxy-Connection: keep-alive\r\n\r\n"),
7719
7720 // After restarting with an identity.
7721 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7722 "Host: origin:443\r\n"
7723 "Proxy-Connection: keep-alive\r\n"
7724 "Proxy-Authorization: NTLM "),
7725 MockWrite(negotiate_msg.c_str()),
7726 // End headers.
7727 MockWrite("\r\n\r\n"),
7728
7729 // The second restart.
7730 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7731 "Host: origin:443\r\n"
7732 "Proxy-Connection: keep-alive\r\n"
7733 "Proxy-Authorization: NTLM "),
7734 MockWrite(authenticate_msg.c_str()),
7735 // End headers.
7736 MockWrite("\r\n\r\n"),
7737 };
7738
7739 MockRead data_reads[] = {
7740 // The initial NTLM response.
7741 MockRead("HTTP/1.1 407 Access Denied\r\n"
7742 "Content-Length: 0\r\n"
7743 "Proxy-Authenticate: NTLM\r\n\r\n"),
7744
7745 // The NTLM challenge message.
7746 MockRead("HTTP/1.1 407 Access Denied\r\n"
7747 "Content-Length: 0\r\n"
7748 "Proxy-Authenticate: NTLM "),
7749 MockRead(challenge_msg.c_str()),
7750 // End headers.
7751 MockRead("\r\n\r\n"),
7752
7753 // Finally the tunnel is established.
7754 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
7755 };
7756
Ryan Sleevib8d7ea02018-05-07 20:01:017757 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497758 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
Ryan Sleevib8d7ea02018-05-07 20:01:017759 StaticSocketDataProvider data2(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497760 SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
Steven Valdez0ef94d02018-11-19 23:28:137761 data_ssl2.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
David Benjamin5cb91132018-04-06 05:54:497762 session_deps_.socket_factory->AddSocketDataProvider(&data);
7763 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
7764 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7765 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
7766
7767 // Start the transaction. The proxy responds with an NTLM authentication
7768 // request.
7769 TestCompletionCallback callback;
7770 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7771 int rv = callback.GetResult(
7772 trans.Start(&request, callback.callback(), NetLogWithSource()));
7773
7774 EXPECT_THAT(rv, IsOk());
7775 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7776 const HttpResponseInfo* response = trans.GetResponseInfo();
7777 ASSERT_TRUE(response);
7778 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get()));
7779
7780 // Configure credentials. The proxy responds with the challenge message.
7781 rv = callback.GetResult(trans.RestartWithAuth(
7782 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7783 callback.callback()));
7784 EXPECT_THAT(rv, IsOk());
7785 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7786 response = trans.GetResponseInfo();
7787 ASSERT_TRUE(response);
7788 EXPECT_FALSE(response->auth_challenge);
7789
7790 // Restart once more. The tunnel will be established and the the SSL handshake
7791 // will reset. The TLS 1.3 version interference probe will then kick in and
7792 // restart the process. The proxy responds with another NTLM authentiation
7793 // request, but we don't need to provide credentials as the cached ones work/
7794 rv = callback.GetResult(
7795 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7796 EXPECT_THAT(rv, IsOk());
7797 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7798 response = trans.GetResponseInfo();
7799 ASSERT_TRUE(response);
7800 EXPECT_FALSE(response->auth_challenge);
7801
7802 // The proxy responds with the NTLM challenge message.
7803 rv = callback.GetResult(
7804 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7805 EXPECT_THAT(rv, IsOk());
7806 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7807 response = trans.GetResponseInfo();
7808 ASSERT_TRUE(response);
7809 EXPECT_FALSE(response->auth_challenge);
7810
7811 // Send the NTLM authenticate message. The tunnel is established and the
7812 // handshake resets again. We should not retry again.
7813 rv = callback.GetResult(
7814 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7815 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
7816}
7817
[email protected]ea9dc9a2009-09-05 00:43:327818#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:297819
[email protected]4ddaf2502008-10-23 18:26:197820// Test reading a server response which has only headers, and no body.
7821// After some maximum number of bytes is consumed, the transaction should
7822// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:017823TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:427824 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:197825 request.method = "GET";
bncce36dca22015-04-21 22:11:237826 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107827 request.traffic_annotation =
7828 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:197829
danakj1fd259a02016-04-16 03:17:097830 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167831 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277832
[email protected]b75b7b2f2009-10-06 00:54:537833 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:437834 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:537835 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:197836
7837 MockRead data_reads[] = {
7838 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:067839 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:197840 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:067841 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:197842 };
Ryan Sleevib8d7ea02018-05-07 20:01:017843 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077844 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:197845
[email protected]49639fa2011-12-20 23:22:417846 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:197847
tfarina42834112016-09-22 13:38:207848 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017849 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:197850
7851 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017852 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197853}
[email protected]f4e426b2008-11-05 00:24:497854
7855// Make sure that we don't try to reuse a TCPClientSocket when failing to
7856// establish tunnel.
7857// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017858TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277859 HttpRequestInfo request;
7860 request.method = "GET";
bncce36dca22015-04-21 22:11:237861 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107862 request.traffic_annotation =
7863 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277864
[email protected]f4e426b2008-11-05 00:24:497865 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497866 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7867 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017868
danakj1fd259a02016-04-16 03:17:097869 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497870
bnc87dcefc2017-05-25 12:47:587871 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197872 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497873
[email protected]f4e426b2008-11-05 00:24:497874 // Since we have proxy, should try to establish tunnel.
7875 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177876 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7877 "Host: www.example.org:443\r\n"
7878 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497879 };
7880
[email protected]77848d12008-11-14 00:00:227881 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497882 // connection. Usually a proxy would return 501 (not implemented),
7883 // or 200 (tunnel established).
7884 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237885 MockRead("HTTP/1.1 404 Not Found\r\n"),
7886 MockRead("Content-Length: 10\r\n\r\n"),
7887 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497888 };
7889
Ryan Sleevib8d7ea02018-05-07 20:01:017890 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:077891 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497892
[email protected]49639fa2011-12-20 23:22:417893 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497894
tfarina42834112016-09-22 13:38:207895 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497897
7898 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017899 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497900
[email protected]b4404c02009-04-10 16:38:527901 // Empty the current queue. This is necessary because idle sockets are
7902 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557903 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527904
[email protected]f4e426b2008-11-05 00:24:497905 // We now check to make sure the TCPClientSocket was not added back to
7906 // the pool.
[email protected]90499482013-06-01 00:39:507907 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497908 trans.reset();
fdoray92e35a72016-06-10 15:54:557909 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497910 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507911 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497912}
[email protected]372d34a2008-11-05 21:30:517913
[email protected]1b157c02009-04-21 01:55:407914// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017915TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427916 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407917 request.method = "GET";
bncce36dca22015-04-21 22:11:237918 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107919 request.traffic_annotation =
7920 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407921
danakj1fd259a02016-04-16 03:17:097922 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277923
bnc691fda62016-08-12 00:43:167924 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277925
[email protected]1b157c02009-04-21 01:55:407926 MockRead data_reads[] = {
7927 // A part of the response body is received with the response headers.
7928 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7929 // The rest of the response body is received in two parts.
7930 MockRead("lo"),
7931 MockRead(" world"),
7932 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067933 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407934 };
7935
Ryan Sleevib8d7ea02018-05-07 20:01:017936 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077937 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407938
[email protected]49639fa2011-12-20 23:22:417939 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407940
tfarina42834112016-09-22 13:38:207941 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017942 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407943
7944 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017945 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407946
bnc691fda62016-08-12 00:43:167947 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527948 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407949
wezca1070932016-05-26 20:30:527950 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407951 std::string status_line = response->headers->GetStatusLine();
7952 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7953
[email protected]90499482013-06-01 00:39:507954 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407955
7956 std::string response_data;
bnc691fda62016-08-12 00:43:167957 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017958 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407959 EXPECT_EQ("hello world", response_data);
7960
7961 // Empty the current queue. This is necessary because idle sockets are
7962 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557963 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407964
7965 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507966 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407967}
7968
[email protected]76a505b2010-08-25 06:23:007969// Make sure that we recycle a SSL socket after reading all of the response
7970// body.
bncd16676a2016-07-20 16:23:017971TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007972 HttpRequestInfo request;
7973 request.method = "GET";
bncce36dca22015-04-21 22:11:237974 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107975 request.traffic_annotation =
7976 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007977
7978 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237979 MockWrite(
7980 "GET / HTTP/1.1\r\n"
7981 "Host: www.example.org\r\n"
7982 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007983 };
7984
7985 MockRead data_reads[] = {
7986 MockRead("HTTP/1.1 200 OK\r\n"),
7987 MockRead("Content-Length: 11\r\n\r\n"),
7988 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067989 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007990 };
7991
[email protected]8ddf8322012-02-23 18:08:067992 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077993 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007994
Ryan Sleevib8d7ea02018-05-07 20:01:017995 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:077996 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007997
[email protected]49639fa2011-12-20 23:22:417998 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007999
danakj1fd259a02016-04-16 03:17:098000 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168001 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008002
tfarina42834112016-09-22 13:38:208003 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008004
robpercival214763f2016-07-01 23:27:018005 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8006 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008007
bnc691fda62016-08-12 00:43:168008 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528009 ASSERT_TRUE(response);
8010 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008011 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8012
[email protected]90499482013-06-01 00:39:508013 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008014
8015 std::string response_data;
bnc691fda62016-08-12 00:43:168016 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018017 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008018 EXPECT_EQ("hello world", response_data);
8019
8020 // Empty the current queue. This is necessary because idle sockets are
8021 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558022 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008023
8024 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238025 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008026}
8027
8028// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
8029// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:018030TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:008031 HttpRequestInfo request;
8032 request.method = "GET";
bncce36dca22015-04-21 22:11:238033 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108034 request.traffic_annotation =
8035 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:008036
8037 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238038 MockWrite(
8039 "GET / HTTP/1.1\r\n"
8040 "Host: www.example.org\r\n"
8041 "Connection: keep-alive\r\n\r\n"),
8042 MockWrite(
8043 "GET / HTTP/1.1\r\n"
8044 "Host: www.example.org\r\n"
8045 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:008046 };
8047
8048 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:428049 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8050 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:008051
[email protected]8ddf8322012-02-23 18:08:068052 SSLSocketDataProvider ssl(ASYNC, OK);
8053 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078054 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8055 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:008056
Ryan Sleevib8d7ea02018-05-07 20:01:018057 StaticSocketDataProvider data(data_reads, data_writes);
8058 StaticSocketDataProvider data2(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078059 session_deps_.socket_factory->AddSocketDataProvider(&data);
8060 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:008061
[email protected]49639fa2011-12-20 23:22:418062 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008063
danakj1fd259a02016-04-16 03:17:098064 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:588065 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198066 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008067
tfarina42834112016-09-22 13:38:208068 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008069
robpercival214763f2016-07-01 23:27:018070 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8071 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008072
8073 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528074 ASSERT_TRUE(response);
8075 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008076 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8077
[email protected]90499482013-06-01 00:39:508078 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008079
8080 std::string response_data;
8081 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018082 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008083 EXPECT_EQ("hello world", response_data);
8084
8085 // Empty the current queue. This is necessary because idle sockets are
8086 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558087 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008088
8089 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238090 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008091
8092 // Now start the second transaction, which should reuse the previous socket.
8093
bnc87dcefc2017-05-25 12:47:588094 trans =
Jeremy Roman0579ed62017-08-29 15:56:198095 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008096
tfarina42834112016-09-22 13:38:208097 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008098
robpercival214763f2016-07-01 23:27:018099 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8100 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008101
8102 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528103 ASSERT_TRUE(response);
8104 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008105 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8106
[email protected]90499482013-06-01 00:39:508107 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008108
8109 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018110 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008111 EXPECT_EQ("hello world", response_data);
8112
8113 // Empty the current queue. This is necessary because idle sockets are
8114 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558115 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008116
8117 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238118 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008119}
8120
maksim.sisov0adf8592016-07-15 06:25:568121// Grab a socket, use it, and put it back into the pool. Then, make
8122// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018123TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568124 HttpRequestInfo request;
8125 request.method = "GET";
8126 request.url = GURL("http://www.example.org/");
8127 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108128 request.traffic_annotation =
8129 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568130
8131 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8132
bnc691fda62016-08-12 00:43:168133 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568134
8135 MockRead data_reads[] = {
8136 // A part of the response body is received with the response headers.
8137 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8138 // The rest of the response body is received in two parts.
8139 MockRead("lo"), MockRead(" world"),
8140 MockRead("junk"), // Should not be read!!
8141 MockRead(SYNCHRONOUS, OK),
8142 };
8143
Ryan Sleevib8d7ea02018-05-07 20:01:018144 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
maksim.sisov0adf8592016-07-15 06:25:568145 session_deps_.socket_factory->AddSocketDataProvider(&data);
8146
8147 TestCompletionCallback callback;
8148
tfarina42834112016-09-22 13:38:208149 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568150 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8151
8152 EXPECT_THAT(callback.GetResult(rv), IsOk());
8153
bnc691fda62016-08-12 00:43:168154 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568155 ASSERT_TRUE(response);
8156 EXPECT_TRUE(response->headers);
8157 std::string status_line = response->headers->GetStatusLine();
8158 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8159
8160 // Make memory critical notification and ensure the transaction still has been
8161 // operating right.
8162 base::MemoryPressureListener::NotifyMemoryPressure(
8163 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8164 base::RunLoop().RunUntilIdle();
8165
8166 // Socket should not be flushed as long as it is not idle.
8167 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8168
8169 std::string response_data;
bnc691fda62016-08-12 00:43:168170 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568171 EXPECT_THAT(rv, IsOk());
8172 EXPECT_EQ("hello world", response_data);
8173
8174 // Empty the current queue. This is necessary because idle sockets are
8175 // added to the connection pool asynchronously with a PostTask.
8176 base::RunLoop().RunUntilIdle();
8177
8178 // We now check to make sure the socket was added back to the pool.
8179 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8180
8181 // Idle sockets should be flushed now.
8182 base::MemoryPressureListener::NotifyMemoryPressure(
8183 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8184 base::RunLoop().RunUntilIdle();
8185
8186 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8187}
8188
yucliu48f235d2018-01-11 00:59:558189// Disable idle socket closing on memory pressure.
8190// Grab a socket, use it, and put it back into the pool. Then, make
8191// low memory notification and ensure the socket pool is NOT flushed.
8192TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
8193 HttpRequestInfo request;
8194 request.method = "GET";
8195 request.url = GURL("http://www.example.org/");
8196 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108197 request.traffic_annotation =
8198 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:558199
8200 // Disable idle socket closing on memory pressure.
8201 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
8202 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8203
8204 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8205
8206 MockRead data_reads[] = {
8207 // A part of the response body is received with the response headers.
8208 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8209 // The rest of the response body is received in two parts.
8210 MockRead("lo"), MockRead(" world"),
8211 MockRead("junk"), // Should not be read!!
8212 MockRead(SYNCHRONOUS, OK),
8213 };
8214
Ryan Sleevib8d7ea02018-05-07 20:01:018215 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
yucliu48f235d2018-01-11 00:59:558216 session_deps_.socket_factory->AddSocketDataProvider(&data);
8217
8218 TestCompletionCallback callback;
8219
8220 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
8221 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8222
8223 EXPECT_THAT(callback.GetResult(rv), IsOk());
8224
8225 const HttpResponseInfo* response = trans.GetResponseInfo();
8226 ASSERT_TRUE(response);
8227 EXPECT_TRUE(response->headers);
8228 std::string status_line = response->headers->GetStatusLine();
8229 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8230
8231 // Make memory critical notification and ensure the transaction still has been
8232 // operating right.
8233 base::MemoryPressureListener::NotifyMemoryPressure(
8234 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8235 base::RunLoop().RunUntilIdle();
8236
8237 // Socket should not be flushed as long as it is not idle.
8238 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8239
8240 std::string response_data;
8241 rv = ReadTransaction(&trans, &response_data);
8242 EXPECT_THAT(rv, IsOk());
8243 EXPECT_EQ("hello world", response_data);
8244
8245 // Empty the current queue. This is necessary because idle sockets are
8246 // added to the connection pool asynchronously with a PostTask.
8247 base::RunLoop().RunUntilIdle();
8248
8249 // We now check to make sure the socket was added back to the pool.
8250 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8251
8252 // Idle sockets should NOT be flushed on moderate memory pressure.
8253 base::MemoryPressureListener::NotifyMemoryPressure(
8254 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
8255 base::RunLoop().RunUntilIdle();
8256
8257 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8258
8259 // Idle sockets should NOT be flushed on critical memory pressure.
8260 base::MemoryPressureListener::NotifyMemoryPressure(
8261 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8262 base::RunLoop().RunUntilIdle();
8263
8264 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8265}
8266
maksim.sisov0adf8592016-07-15 06:25:568267// Grab an SSL socket, use it, and put it back into the pool. Then, make
8268// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018269TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568270 HttpRequestInfo request;
8271 request.method = "GET";
8272 request.url = GURL("https://www.example.org/");
8273 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108274 request.traffic_annotation =
8275 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568276
8277 MockWrite data_writes[] = {
8278 MockWrite("GET / HTTP/1.1\r\n"
8279 "Host: www.example.org\r\n"
8280 "Connection: keep-alive\r\n\r\n"),
8281 };
8282
8283 MockRead data_reads[] = {
8284 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8285 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
8286
8287 SSLSocketDataProvider ssl(ASYNC, OK);
8288 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8289
Ryan Sleevib8d7ea02018-05-07 20:01:018290 StaticSocketDataProvider data(data_reads, data_writes);
maksim.sisov0adf8592016-07-15 06:25:568291 session_deps_.socket_factory->AddSocketDataProvider(&data);
8292
8293 TestCompletionCallback callback;
8294
8295 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168296 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568297
Matt Menke9d5e2c92019-02-05 01:42:238298 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
tfarina42834112016-09-22 13:38:208299 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568300
8301 EXPECT_THAT(callback.GetResult(rv), IsOk());
8302
bnc691fda62016-08-12 00:43:168303 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568304 ASSERT_TRUE(response);
8305 ASSERT_TRUE(response->headers);
8306 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8307
8308 // Make memory critical notification and ensure the transaction still has been
8309 // operating right.
8310 base::MemoryPressureListener::NotifyMemoryPressure(
8311 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8312 base::RunLoop().RunUntilIdle();
8313
Matt Menke9d5e2c92019-02-05 01:42:238314 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568315
8316 std::string response_data;
bnc691fda62016-08-12 00:43:168317 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568318 EXPECT_THAT(rv, IsOk());
8319 EXPECT_EQ("hello world", response_data);
8320
8321 // Empty the current queue. This is necessary because idle sockets are
8322 // added to the connection pool asynchronously with a PostTask.
8323 base::RunLoop().RunUntilIdle();
8324
8325 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238326 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568327
8328 // Make memory notification once again and ensure idle socket is closed.
8329 base::MemoryPressureListener::NotifyMemoryPressure(
8330 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8331 base::RunLoop().RunUntilIdle();
8332
Matt Menke9d5e2c92019-02-05 01:42:238333 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568334}
8335
[email protected]b4404c02009-04-10 16:38:528336// Make sure that we recycle a socket after a zero-length response.
8337// http://crbug.com/9880
bncd16676a2016-07-20 16:23:018338TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:428339 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:528340 request.method = "GET";
bncce36dca22015-04-21 22:11:238341 request.url = GURL(
8342 "http://www.example.org/csi?v=3&s=web&action=&"
8343 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
8344 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
8345 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e2018-02-07 07:41:108346 request.traffic_annotation =
8347 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:528348
danakj1fd259a02016-04-16 03:17:098349 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278350
[email protected]b4404c02009-04-10 16:38:528351 MockRead data_reads[] = {
8352 MockRead("HTTP/1.1 204 No Content\r\n"
8353 "Content-Length: 0\r\n"
8354 "Content-Type: text/html\r\n\r\n"),
8355 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:068356 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:528357 };
8358
Ryan Sleevib8d7ea02018-05-07 20:01:018359 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:078360 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:528361
mmenkecc2298e2015-12-07 18:20:188362 // Transaction must be created after the MockReads, so it's destroyed before
8363 // them.
bnc691fda62016-08-12 00:43:168364 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:188365
[email protected]49639fa2011-12-20 23:22:418366 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:528367
tfarina42834112016-09-22 13:38:208368 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018369 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:528370
8371 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018372 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528373
bnc691fda62016-08-12 00:43:168374 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528375 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:528376
wezca1070932016-05-26 20:30:528377 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:528378 std::string status_line = response->headers->GetStatusLine();
8379 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
8380
[email protected]90499482013-06-01 00:39:508381 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528382
8383 std::string response_data;
bnc691fda62016-08-12 00:43:168384 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018385 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528386 EXPECT_EQ("", response_data);
8387
8388 // Empty the current queue. This is necessary because idle sockets are
8389 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558390 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:528391
8392 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508393 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528394}
8395
bncd16676a2016-07-20 16:23:018396TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:098397 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:228398 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:198399 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:228400 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:278401
[email protected]1c773ea12009-04-28 19:58:428402 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:518403 // Transaction 1: a GET request that succeeds. The socket is recycled
8404 // after use.
8405 request[0].method = "GET";
8406 request[0].url = GURL("http://www.google.com/");
8407 request[0].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108408 request[0].traffic_annotation =
8409 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518410 // Transaction 2: a POST request. Reuses the socket kept alive from
8411 // transaction 1. The first attempts fails when writing the POST data.
8412 // This causes the transaction to retry with a new socket. The second
8413 // attempt succeeds.
8414 request[1].method = "POST";
8415 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:278416 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:518417 request[1].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:108418 request[1].traffic_annotation =
8419 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518420
danakj1fd259a02016-04-16 03:17:098421 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:518422
8423 // The first socket is used for transaction 1 and the first attempt of
8424 // transaction 2.
8425
8426 // The response of transaction 1.
8427 MockRead data_reads1[] = {
8428 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
8429 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068430 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518431 };
8432 // The mock write results of transaction 1 and the first attempt of
8433 // transaction 2.
8434 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:068435 MockWrite(SYNCHRONOUS, 64), // GET
8436 MockWrite(SYNCHRONOUS, 93), // POST
8437 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:518438 };
Ryan Sleevib8d7ea02018-05-07 20:01:018439 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:518440
8441 // The second socket is used for the second attempt of transaction 2.
8442
8443 // The response of transaction 2.
8444 MockRead data_reads2[] = {
8445 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
8446 MockRead("welcome"),
[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 the second attempt of transaction 2.
8450 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:068451 MockWrite(SYNCHRONOUS, 93), // POST
8452 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:518453 };
Ryan Sleevib8d7ea02018-05-07 20:01:018454 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:518455
[email protected]bb88e1d32013-05-03 23:11:078456 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8457 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:518458
thestig9d3bb0c2015-01-24 00:49:518459 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:518460 "hello world", "welcome"
8461 };
8462
8463 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:168464 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:518465
[email protected]49639fa2011-12-20 23:22:418466 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:518467
tfarina42834112016-09-22 13:38:208468 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018469 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:518470
8471 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018472 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518473
bnc691fda62016-08-12 00:43:168474 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528475 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:518476
wezca1070932016-05-26 20:30:528477 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:518478 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8479
8480 std::string response_data;
bnc691fda62016-08-12 00:43:168481 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018482 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518483 EXPECT_EQ(kExpectedResponseData[i], response_data);
8484 }
8485}
[email protected]f9ee6b52008-11-08 06:46:238486
8487// Test the request-challenge-retry sequence for basic auth when there is
8488// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:168489// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:018490TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:428491 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238492 request.method = "GET";
bncce36dca22015-04-21 22:11:238493 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:418494 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:108495 request.traffic_annotation =
8496 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:298497
danakj1fd259a02016-04-16 03:17:098498 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168499 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278500
[email protected]a97cca42009-08-14 01:00:298501 // The password contains an escaped character -- for this test to pass it
8502 // will need to be unescaped by HttpNetworkTransaction.
8503 EXPECT_EQ("b%40r", request.url.password());
8504
[email protected]f9ee6b52008-11-08 06:46:238505 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238506 MockWrite(
8507 "GET / HTTP/1.1\r\n"
8508 "Host: www.example.org\r\n"
8509 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238510 };
8511
8512 MockRead data_reads1[] = {
8513 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8514 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8515 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068516 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238517 };
8518
[email protected]2262e3a2012-05-22 16:08:168519 // After the challenge above, the transaction will be restarted using the
8520 // identity from the url (foo, b@r) to answer the challenge.
8521 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238522 MockWrite(
8523 "GET / HTTP/1.1\r\n"
8524 "Host: www.example.org\r\n"
8525 "Connection: keep-alive\r\n"
8526 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168527 };
8528
8529 MockRead data_reads2[] = {
8530 MockRead("HTTP/1.0 200 OK\r\n"),
8531 MockRead("Content-Length: 100\r\n\r\n"),
8532 MockRead(SYNCHRONOUS, OK),
8533 };
8534
Ryan Sleevib8d7ea02018-05-07 20:01:018535 StaticSocketDataProvider data1(data_reads1, data_writes1);
8536 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078537 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8538 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238539
[email protected]49639fa2011-12-20 23:22:418540 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208541 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018542 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238543 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018544 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168545 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168546
8547 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168548 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018549 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168550 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018551 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168552 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228553
bnc691fda62016-08-12 00:43:168554 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528555 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168556
8557 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:528558 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168559
8560 EXPECT_EQ(100, response->headers->GetContentLength());
8561
8562 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558563 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:168564}
8565
8566// Test the request-challenge-retry sequence for basic auth when there is an
8567// incorrect identity in the URL. The identity from the URL should be used only
8568// once.
bncd16676a2016-07-20 16:23:018569TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:168570 HttpRequestInfo request;
8571 request.method = "GET";
8572 // Note: the URL has a username:password in it. The password "baz" is
8573 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:238574 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:168575
8576 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:108577 request.traffic_annotation =
8578 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:168579
danakj1fd259a02016-04-16 03:17:098580 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168581 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:168582
8583 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238584 MockWrite(
8585 "GET / HTTP/1.1\r\n"
8586 "Host: www.example.org\r\n"
8587 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168588 };
8589
8590 MockRead data_reads1[] = {
8591 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8592 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8593 MockRead("Content-Length: 10\r\n\r\n"),
8594 MockRead(SYNCHRONOUS, ERR_FAILED),
8595 };
8596
8597 // After the challenge above, the transaction will be restarted using the
8598 // identity from the url (foo, baz) to answer the challenge.
8599 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238600 MockWrite(
8601 "GET / HTTP/1.1\r\n"
8602 "Host: www.example.org\r\n"
8603 "Connection: keep-alive\r\n"
8604 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168605 };
8606
8607 MockRead data_reads2[] = {
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 supplied by the user (foo, bar) to answer the challenge.
8616 MockWrite data_writes3[] = {
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 Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168622 };
8623
8624 MockRead data_reads3[] = {
8625 MockRead("HTTP/1.0 200 OK\r\n"),
8626 MockRead("Content-Length: 100\r\n\r\n"),
8627 MockRead(SYNCHRONOUS, OK),
8628 };
8629
Ryan Sleevib8d7ea02018-05-07 20:01:018630 StaticSocketDataProvider data1(data_reads1, data_writes1);
8631 StaticSocketDataProvider data2(data_reads2, data_writes2);
8632 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:078633 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8634 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8635 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:168636
8637 TestCompletionCallback callback1;
8638
tfarina42834112016-09-22 13:38:208639 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018640 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168641
8642 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018643 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:168644
bnc691fda62016-08-12 00:43:168645 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168646 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168647 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018648 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168649 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018650 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168651 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168652
bnc691fda62016-08-12 00:43:168653 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528654 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168655 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8656
8657 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168658 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018659 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168660 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018661 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168662 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168663
bnc691fda62016-08-12 00:43:168664 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528665 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168666
8667 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528668 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168669
8670 EXPECT_EQ(100, response->headers->GetContentLength());
8671
[email protected]ea9dc9a2009-09-05 00:43:328672 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558673 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:328674}
8675
[email protected]2217aa22013-10-11 03:03:548676
8677// Test the request-challenge-retry sequence for basic auth when there is a
8678// correct identity in the URL, but its use is being suppressed. The identity
8679// from the URL should never be used.
bncd16676a2016-07-20 16:23:018680TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:548681 HttpRequestInfo request;
8682 request.method = "GET";
bncce36dca22015-04-21 22:11:238683 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:548684 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e2018-02-07 07:41:108685 request.traffic_annotation =
8686 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:548687
danakj1fd259a02016-04-16 03:17:098688 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168689 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:548690
8691 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238692 MockWrite(
8693 "GET / HTTP/1.1\r\n"
8694 "Host: www.example.org\r\n"
8695 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548696 };
8697
8698 MockRead data_reads1[] = {
8699 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8700 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8701 MockRead("Content-Length: 10\r\n\r\n"),
8702 MockRead(SYNCHRONOUS, ERR_FAILED),
8703 };
8704
8705 // After the challenge above, the transaction will be restarted using the
8706 // identity supplied by the user, not the one in the URL, to answer the
8707 // challenge.
8708 MockWrite data_writes3[] = {
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"
8713 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548714 };
8715
8716 MockRead data_reads3[] = {
8717 MockRead("HTTP/1.0 200 OK\r\n"),
8718 MockRead("Content-Length: 100\r\n\r\n"),
8719 MockRead(SYNCHRONOUS, OK),
8720 };
8721
Ryan Sleevib8d7ea02018-05-07 20:01:018722 StaticSocketDataProvider data1(data_reads1, data_writes1);
8723 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]2217aa22013-10-11 03:03:548724 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8725 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8726
8727 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208728 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018729 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548730 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018731 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168732 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548733
bnc691fda62016-08-12 00:43:168734 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528735 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548736 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8737
8738 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168739 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548741 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018742 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168743 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548744
bnc691fda62016-08-12 00:43:168745 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528746 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548747
8748 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528749 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:548750 EXPECT_EQ(100, response->headers->GetContentLength());
8751
8752 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558753 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:548754}
8755
[email protected]f9ee6b52008-11-08 06:46:238756// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:018757TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:098758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:238759
8760 // Transaction 1: authenticate (foo, bar) on MyRealm1
8761 {
[email protected]1c773ea12009-04-28 19:58:428762 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238763 request.method = "GET";
bncce36dca22015-04-21 22:11:238764 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:108765 request.traffic_annotation =
8766 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238767
bnc691fda62016-08-12 00:43:168768 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278769
[email protected]f9ee6b52008-11-08 06:46:238770 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238771 MockWrite(
8772 "GET /x/y/z HTTP/1.1\r\n"
8773 "Host: www.example.org\r\n"
8774 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238775 };
8776
8777 MockRead data_reads1[] = {
8778 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8779 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8780 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068781 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238782 };
8783
8784 // Resend with authorization (username=foo, password=bar)
8785 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238786 MockWrite(
8787 "GET /x/y/z HTTP/1.1\r\n"
8788 "Host: www.example.org\r\n"
8789 "Connection: keep-alive\r\n"
8790 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238791 };
8792
8793 // Sever accepts the authorization.
8794 MockRead data_reads2[] = {
8795 MockRead("HTTP/1.0 200 OK\r\n"),
8796 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068797 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238798 };
8799
Ryan Sleevib8d7ea02018-05-07 20:01:018800 StaticSocketDataProvider data1(data_reads1, data_writes1);
8801 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078802 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8803 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238804
[email protected]49639fa2011-12-20 23:22:418805 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238806
tfarina42834112016-09-22 13:38:208807 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018808 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238809
8810 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018811 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238812
bnc691fda62016-08-12 00:43:168813 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528814 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048815 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238816
[email protected]49639fa2011-12-20 23:22:418817 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238818
bnc691fda62016-08-12 00:43:168819 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8820 callback2.callback());
robpercival214763f2016-07-01 23:27:018821 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238822
8823 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018824 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238825
bnc691fda62016-08-12 00:43:168826 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528827 ASSERT_TRUE(response);
8828 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238829 EXPECT_EQ(100, response->headers->GetContentLength());
8830 }
8831
8832 // ------------------------------------------------------------------------
8833
8834 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
8835 {
[email protected]1c773ea12009-04-28 19:58:428836 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238837 request.method = "GET";
8838 // Note that Transaction 1 was at /x/y/z, so this is in the same
8839 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:238840 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:108841 request.traffic_annotation =
8842 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238843
bnc691fda62016-08-12 00:43:168844 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278845
[email protected]f9ee6b52008-11-08 06:46:238846 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238847 MockWrite(
8848 "GET /x/y/a/b HTTP/1.1\r\n"
8849 "Host: www.example.org\r\n"
8850 "Connection: keep-alive\r\n"
8851 // Send preemptive authorization for MyRealm1
8852 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238853 };
8854
8855 // The server didn't like the preemptive authorization, and
8856 // challenges us for a different realm (MyRealm2).
8857 MockRead data_reads1[] = {
8858 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8859 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8860 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068861 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238862 };
8863
8864 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8865 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238866 MockWrite(
8867 "GET /x/y/a/b HTTP/1.1\r\n"
8868 "Host: www.example.org\r\n"
8869 "Connection: keep-alive\r\n"
8870 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238871 };
8872
8873 // Sever accepts the authorization.
8874 MockRead data_reads2[] = {
8875 MockRead("HTTP/1.0 200 OK\r\n"),
8876 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068877 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238878 };
8879
Ryan Sleevib8d7ea02018-05-07 20:01:018880 StaticSocketDataProvider data1(data_reads1, data_writes1);
8881 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078882 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8883 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238884
[email protected]49639fa2011-12-20 23:22:418885 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238886
tfarina42834112016-09-22 13:38:208887 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018888 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238889
8890 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018891 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238892
bnc691fda62016-08-12 00:43:168893 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528894 ASSERT_TRUE(response);
8895 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048896 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438897 EXPECT_EQ("http://www.example.org",
8898 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048899 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198900 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238901
[email protected]49639fa2011-12-20 23:22:418902 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238903
bnc691fda62016-08-12 00:43:168904 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8905 callback2.callback());
robpercival214763f2016-07-01 23:27:018906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238907
8908 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018909 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238910
bnc691fda62016-08-12 00:43:168911 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528912 ASSERT_TRUE(response);
8913 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238914 EXPECT_EQ(100, response->headers->GetContentLength());
8915 }
8916
8917 // ------------------------------------------------------------------------
8918
8919 // Transaction 3: Resend a request in MyRealm's protection space --
8920 // succeed with preemptive authorization.
8921 {
[email protected]1c773ea12009-04-28 19:58:428922 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238923 request.method = "GET";
bncce36dca22015-04-21 22:11:238924 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e2018-02-07 07:41:108925 request.traffic_annotation =
8926 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238927
bnc691fda62016-08-12 00:43:168928 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278929
[email protected]f9ee6b52008-11-08 06:46:238930 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238931 MockWrite(
8932 "GET /x/y/z2 HTTP/1.1\r\n"
8933 "Host: www.example.org\r\n"
8934 "Connection: keep-alive\r\n"
8935 // The authorization for MyRealm1 gets sent preemptively
8936 // (since the url is in the same protection space)
8937 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238938 };
8939
8940 // Sever accepts the preemptive authorization
8941 MockRead data_reads1[] = {
8942 MockRead("HTTP/1.0 200 OK\r\n"),
8943 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068944 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238945 };
8946
Ryan Sleevib8d7ea02018-05-07 20:01:018947 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078948 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238949
[email protected]49639fa2011-12-20 23:22:418950 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238951
tfarina42834112016-09-22 13:38:208952 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018953 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238954
8955 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018956 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238957
bnc691fda62016-08-12 00:43:168958 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528959 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238960
wezca1070932016-05-26 20:30:528961 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238962 EXPECT_EQ(100, response->headers->GetContentLength());
8963 }
8964
8965 // ------------------------------------------------------------------------
8966
8967 // Transaction 4: request another URL in MyRealm (however the
8968 // url is not known to belong to the protection space, so no pre-auth).
8969 {
[email protected]1c773ea12009-04-28 19:58:428970 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238971 request.method = "GET";
bncce36dca22015-04-21 22:11:238972 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e2018-02-07 07:41:108973 request.traffic_annotation =
8974 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238975
bnc691fda62016-08-12 00:43:168976 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278977
[email protected]f9ee6b52008-11-08 06:46:238978 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238979 MockWrite(
8980 "GET /x/1 HTTP/1.1\r\n"
8981 "Host: www.example.org\r\n"
8982 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238983 };
8984
8985 MockRead data_reads1[] = {
8986 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8987 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8988 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068989 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238990 };
8991
8992 // Resend with authorization from MyRealm's cache.
8993 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238994 MockWrite(
8995 "GET /x/1 HTTP/1.1\r\n"
8996 "Host: www.example.org\r\n"
8997 "Connection: keep-alive\r\n"
8998 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238999 };
9000
9001 // Sever accepts the authorization.
9002 MockRead data_reads2[] = {
9003 MockRead("HTTP/1.0 200 OK\r\n"),
9004 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069005 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239006 };
9007
Ryan Sleevib8d7ea02018-05-07 20:01:019008 StaticSocketDataProvider data1(data_reads1, data_writes1);
9009 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079010 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9011 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:239012
[email protected]49639fa2011-12-20 23:22:419013 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239014
tfarina42834112016-09-22 13:38:209015 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019016 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239017
9018 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019019 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239020
bnc691fda62016-08-12 00:43:169021 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419022 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169023 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019024 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229025 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019026 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169027 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229028
bnc691fda62016-08-12 00:43:169029 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529030 ASSERT_TRUE(response);
9031 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239032 EXPECT_EQ(100, response->headers->GetContentLength());
9033 }
9034
9035 // ------------------------------------------------------------------------
9036
9037 // Transaction 5: request a URL in MyRealm, but the server rejects the
9038 // cached identity. Should invalidate and re-prompt.
9039 {
[email protected]1c773ea12009-04-28 19:58:429040 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:239041 request.method = "GET";
bncce36dca22015-04-21 22:11:239042 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e2018-02-07 07:41:109043 request.traffic_annotation =
9044 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:239045
bnc691fda62016-08-12 00:43:169046 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279047
[email protected]f9ee6b52008-11-08 06:46:239048 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239049 MockWrite(
9050 "GET /p/q/t HTTP/1.1\r\n"
9051 "Host: www.example.org\r\n"
9052 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239053 };
9054
9055 MockRead data_reads1[] = {
9056 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9057 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9058 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069059 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239060 };
9061
9062 // Resend with authorization from cache for MyRealm.
9063 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239064 MockWrite(
9065 "GET /p/q/t HTTP/1.1\r\n"
9066 "Host: www.example.org\r\n"
9067 "Connection: keep-alive\r\n"
9068 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239069 };
9070
9071 // Sever rejects the authorization.
9072 MockRead data_reads2[] = {
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 // At this point we should prompt for new credentials for MyRealm.
9080 // Restart with username=foo3, password=foo4.
9081 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239082 MockWrite(
9083 "GET /p/q/t HTTP/1.1\r\n"
9084 "Host: www.example.org\r\n"
9085 "Connection: keep-alive\r\n"
9086 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239087 };
9088
9089 // Sever accepts the authorization.
9090 MockRead data_reads3[] = {
9091 MockRead("HTTP/1.0 200 OK\r\n"),
9092 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069093 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239094 };
9095
Ryan Sleevib8d7ea02018-05-07 20:01:019096 StaticSocketDataProvider data1(data_reads1, data_writes1);
9097 StaticSocketDataProvider data2(data_reads2, data_writes2);
9098 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:079099 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9100 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9101 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:239102
[email protected]49639fa2011-12-20 23:22:419103 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239104
tfarina42834112016-09-22 13:38:209105 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019106 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239107
9108 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019109 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239110
bnc691fda62016-08-12 00:43:169111 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419112 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169113 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229115 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019116 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169117 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229118
bnc691fda62016-08-12 00:43:169119 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529120 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049121 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:239122
[email protected]49639fa2011-12-20 23:22:419123 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:239124
bnc691fda62016-08-12 00:43:169125 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
9126 callback3.callback());
robpercival214763f2016-07-01 23:27:019127 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239128
[email protected]0757e7702009-03-27 04:00:229129 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:019130 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239131
bnc691fda62016-08-12 00:43:169132 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529133 ASSERT_TRUE(response);
9134 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239135 EXPECT_EQ(100, response->headers->GetContentLength());
9136 }
9137}
[email protected]89ceba9a2009-03-21 03:46:069138
[email protected]3c32c5f2010-05-18 15:18:129139// Tests that nonce count increments when multiple auth attempts
9140// are started with the same nonce.
bncd16676a2016-07-20 16:23:019141TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:449142 HttpAuthHandlerDigest::Factory* digest_factory =
9143 new HttpAuthHandlerDigest::Factory();
9144 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
9145 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
9146 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:079147 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:099148 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:129149
9150 // Transaction 1: authenticate (foo, bar) on MyRealm1
9151 {
[email protected]3c32c5f2010-05-18 15:18:129152 HttpRequestInfo request;
9153 request.method = "GET";
bncce36dca22015-04-21 22:11:239154 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:109155 request.traffic_annotation =
9156 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129157
bnc691fda62016-08-12 00:43:169158 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279159
[email protected]3c32c5f2010-05-18 15:18:129160 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239161 MockWrite(
9162 "GET /x/y/z HTTP/1.1\r\n"
9163 "Host: www.example.org\r\n"
9164 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129165 };
9166
9167 MockRead data_reads1[] = {
9168 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9169 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
9170 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069171 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129172 };
9173
9174 // Resend with authorization (username=foo, password=bar)
9175 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239176 MockWrite(
9177 "GET /x/y/z HTTP/1.1\r\n"
9178 "Host: www.example.org\r\n"
9179 "Connection: keep-alive\r\n"
9180 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9181 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
9182 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
9183 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129184 };
9185
9186 // Sever accepts the authorization.
9187 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:089188 MockRead("HTTP/1.0 200 OK\r\n"),
9189 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129190 };
9191
Ryan Sleevib8d7ea02018-05-07 20:01:019192 StaticSocketDataProvider data1(data_reads1, data_writes1);
9193 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079194 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9195 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:129196
[email protected]49639fa2011-12-20 23:22:419197 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129198
tfarina42834112016-09-22 13:38:209199 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019200 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129201
9202 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019203 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129204
bnc691fda62016-08-12 00:43:169205 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529206 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049207 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:129208
[email protected]49639fa2011-12-20 23:22:419209 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:129210
bnc691fda62016-08-12 00:43:169211 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
9212 callback2.callback());
robpercival214763f2016-07-01 23:27:019213 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129214
9215 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019216 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129217
bnc691fda62016-08-12 00:43:169218 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529219 ASSERT_TRUE(response);
9220 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129221 }
9222
9223 // ------------------------------------------------------------------------
9224
9225 // Transaction 2: Request another resource in digestive's protection space.
9226 // This will preemptively add an Authorization header which should have an
9227 // "nc" value of 2 (as compared to 1 in the first use.
9228 {
[email protected]3c32c5f2010-05-18 15:18:129229 HttpRequestInfo request;
9230 request.method = "GET";
9231 // Note that Transaction 1 was at /x/y/z, so this is in the same
9232 // protection space as digest.
bncce36dca22015-04-21 22:11:239233 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:109234 request.traffic_annotation =
9235 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129236
bnc691fda62016-08-12 00:43:169237 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279238
[email protected]3c32c5f2010-05-18 15:18:129239 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239240 MockWrite(
9241 "GET /x/y/a/b HTTP/1.1\r\n"
9242 "Host: www.example.org\r\n"
9243 "Connection: keep-alive\r\n"
9244 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9245 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
9246 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
9247 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129248 };
9249
9250 // Sever accepts the authorization.
9251 MockRead data_reads1[] = {
9252 MockRead("HTTP/1.0 200 OK\r\n"),
9253 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069254 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129255 };
9256
Ryan Sleevib8d7ea02018-05-07 20:01:019257 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:079258 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:129259
[email protected]49639fa2011-12-20 23:22:419260 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129261
tfarina42834112016-09-22 13:38:209262 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019263 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129264
9265 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019266 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129267
bnc691fda62016-08-12 00:43:169268 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529269 ASSERT_TRUE(response);
9270 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129271 }
9272}
9273
[email protected]89ceba9a2009-03-21 03:46:069274// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:019275TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:069276 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:099277 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169278 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:069279
9280 // Setup some state (which we expect ResetStateForRestart() will clear).
Victor Costan9c7302b2018-08-27 16:39:449281 trans.read_buf_ = base::MakeRefCounted<IOBuffer>(15);
bnc691fda62016-08-12 00:43:169282 trans.read_buf_len_ = 15;
9283 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:069284
9285 // Setup state in response_
bnc691fda62016-08-12 00:43:169286 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:579287 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:089288 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:579289 response->response_time = base::Time::Now();
9290 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:069291
9292 { // Setup state for response_.vary_data
9293 HttpRequestInfo request;
9294 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
9295 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:279296 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:439297 request.extra_headers.SetHeader("Foo", "1");
9298 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:509299 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:069300 }
9301
9302 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:169303 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:069304
9305 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:169306 EXPECT_FALSE(trans.read_buf_);
9307 EXPECT_EQ(0, trans.read_buf_len_);
9308 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:529309 EXPECT_FALSE(response->auth_challenge);
9310 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:049311 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:089312 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:579313 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:069314}
9315
[email protected]bacff652009-03-31 17:50:339316// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:019317TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:339318 HttpRequestInfo request;
9319 request.method = "GET";
bncce36dca22015-04-21 22:11:239320 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109321 request.traffic_annotation =
9322 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339323
danakj1fd259a02016-04-16 03:17:099324 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169325 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279326
[email protected]bacff652009-03-31 17:50:339327 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239328 MockWrite(
9329 "GET / HTTP/1.1\r\n"
9330 "Host: www.example.org\r\n"
9331 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339332 };
9333
9334 MockRead data_reads[] = {
9335 MockRead("HTTP/1.0 200 OK\r\n"),
9336 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9337 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069338 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339339 };
9340
[email protected]5ecc992a42009-11-11 01:41:599341 StaticSocketDataProvider ssl_bad_certificate;
Ryan Sleevib8d7ea02018-05-07 20:01:019342 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069343 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9344 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339345
[email protected]bb88e1d32013-05-03 23:11:079346 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9347 session_deps_.socket_factory->AddSocketDataProvider(&data);
9348 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9349 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339350
[email protected]49639fa2011-12-20 23:22:419351 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339352
tfarina42834112016-09-22 13:38:209353 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019354 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339355
9356 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019357 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339358
bnc691fda62016-08-12 00:43:169359 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019360 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339361
9362 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019363 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339364
bnc691fda62016-08-12 00:43:169365 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339366
wezca1070932016-05-26 20:30:529367 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339368 EXPECT_EQ(100, response->headers->GetContentLength());
9369}
9370
9371// Test HTTPS connections to a site with a bad certificate, going through a
9372// proxy
bncd16676a2016-07-20 16:23:019373TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499374 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9375 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339376
9377 HttpRequestInfo request;
9378 request.method = "GET";
bncce36dca22015-04-21 22:11:239379 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109380 request.traffic_annotation =
9381 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339382
9383 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:179384 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9385 "Host: www.example.org:443\r\n"
9386 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339387 };
9388
9389 MockRead proxy_reads[] = {
9390 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069391 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:339392 };
9393
9394 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179395 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9396 "Host: www.example.org:443\r\n"
9397 "Proxy-Connection: keep-alive\r\n\r\n"),
9398 MockWrite("GET / HTTP/1.1\r\n"
9399 "Host: www.example.org\r\n"
9400 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339401 };
9402
9403 MockRead data_reads[] = {
9404 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9405 MockRead("HTTP/1.0 200 OK\r\n"),
9406 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9407 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069408 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339409 };
9410
Ryan Sleevib8d7ea02018-05-07 20:01:019411 StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
9412 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069413 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9414 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339415
[email protected]bb88e1d32013-05-03 23:11:079416 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9417 session_deps_.socket_factory->AddSocketDataProvider(&data);
9418 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9419 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339420
[email protected]49639fa2011-12-20 23:22:419421 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339422
9423 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:079424 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:339425
danakj1fd259a02016-04-16 03:17:099426 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169427 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:339428
tfarina42834112016-09-22 13:38:209429 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019430 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339431
9432 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019433 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339434
bnc691fda62016-08-12 00:43:169435 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019436 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339437
9438 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019439 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339440
bnc691fda62016-08-12 00:43:169441 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339442
wezca1070932016-05-26 20:30:529443 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339444 EXPECT_EQ(100, response->headers->GetContentLength());
9445 }
9446}
9447
[email protected]2df19bb2010-08-25 20:13:469448
9449// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:019450TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599451 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499452 ProxyResolutionService::CreateFixedFromPacResult(
9453 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519454 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079455 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:469456
9457 HttpRequestInfo request;
9458 request.method = "GET";
bncce36dca22015-04-21 22:11:239459 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109460 request.traffic_annotation =
9461 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469462
9463 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179464 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9465 "Host: www.example.org:443\r\n"
9466 "Proxy-Connection: keep-alive\r\n\r\n"),
9467 MockWrite("GET / HTTP/1.1\r\n"
9468 "Host: www.example.org\r\n"
9469 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469470 };
9471
9472 MockRead data_reads[] = {
9473 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9474 MockRead("HTTP/1.1 200 OK\r\n"),
9475 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9476 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069477 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469478 };
9479
Ryan Sleevib8d7ea02018-05-07 20:01:019480 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069481 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9482 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:469483
[email protected]bb88e1d32013-05-03 23:11:079484 session_deps_.socket_factory->AddSocketDataProvider(&data);
9485 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9486 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:469487
[email protected]49639fa2011-12-20 23:22:419488 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469489
danakj1fd259a02016-04-16 03:17:099490 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169491 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469492
tfarina42834112016-09-22 13:38:209493 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019494 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469495
9496 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019497 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169498 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469499
wezca1070932016-05-26 20:30:529500 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469501
tbansal2ecbbc72016-10-06 17:15:479502 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:469503 EXPECT_TRUE(response->headers->IsKeepAlive());
9504 EXPECT_EQ(200, response->headers->response_code());
9505 EXPECT_EQ(100, response->headers->GetContentLength());
9506 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209507
9508 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169509 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209510 TestLoadTimingNotReusedWithPac(load_timing_info,
9511 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:469512}
9513
Eric Roman74103c72019-02-21 00:23:129514// Test that an HTTPS Proxy can redirect a CONNECT request for main frames.
bncd16676a2016-07-20 16:23:019515TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599516 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499517 ProxyResolutionService::CreateFixedFromPacResult(
9518 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519519 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079520 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:299521
Matt Menkeecfecfc72019-02-05 19:15:289522 base::TimeTicks start_time = base::TimeTicks::Now();
9523 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9524 session_deps_.host_resolver->set_ondemand_mode(true);
9525
[email protected]511f6f52010-12-17 03:58:299526 HttpRequestInfo request;
Eric Roman74103c72019-02-21 00:23:129527 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
[email protected]511f6f52010-12-17 03:58:299528 request.method = "GET";
bncce36dca22015-04-21 22:11:239529 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109530 request.traffic_annotation =
9531 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299532
9533 MockWrite data_writes[] = {
Matt Menkeecfecfc72019-02-05 19:15:289534 MockWrite(ASYNC, 0,
9535 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:179536 "Host: www.example.org:443\r\n"
9537 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299538 };
9539
9540 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289541 // Pause on first read.
9542 MockRead(ASYNC, ERR_IO_PENDING, 1),
9543 MockRead(ASYNC, 2, "HTTP/1.1 302 Redirect\r\n"),
9544 MockRead(ASYNC, 3, "Location: http://login.example.com/\r\n"),
9545 MockRead(ASYNC, 4, "Content-Length: 0\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299546 };
9547
Matt Menkeecfecfc72019-02-05 19:15:289548 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069549 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299550
[email protected]bb88e1d32013-05-03 23:11:079551 session_deps_.socket_factory->AddSocketDataProvider(&data);
9552 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299553
[email protected]49639fa2011-12-20 23:22:419554 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299555
danakj1fd259a02016-04-16 03:17:099556 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169557 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299558
tfarina42834112016-09-22 13:38:209559 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019560 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289561 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
9562
9563 // Host resolution takes |kTimeIncrement|.
9564 FastForwardBy(kTimeIncrement);
9565 // Resolving the current request with |ResolveNow| will cause the pending
9566 // request to instantly complete, and the async connect will start as well.
9567 session_deps_.host_resolver->ResolveOnlyRequestNow();
9568
9569 // Connecting takes |kTimeIncrement|.
9570 FastForwardBy(kTimeIncrement);
9571 data.RunUntilPaused();
9572
9573 // The server takes |kTimeIncrement| to respond.
9574 FastForwardBy(kTimeIncrement);
9575 data.Resume();
[email protected]511f6f52010-12-17 03:58:299576
9577 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019578 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169579 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299580
wezca1070932016-05-26 20:30:529581 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299582
9583 EXPECT_EQ(302, response->headers->response_code());
9584 std::string url;
9585 EXPECT_TRUE(response->headers->IsRedirect(&url));
9586 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:209587
[email protected]029c83b62013-01-24 05:28:209588 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169589 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209590
9591 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:199592 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:209593
Matt Menkeecfecfc72019-02-05 19:15:289594 // In the case of redirects from proxies, just as with all responses from
9595 // proxies, DNS and SSL times reflect timing to look up the destination's
9596 // name, and negotiate an SSL connection to it (Neither of which are done in
9597 // this case), which the DNS and SSL times for the proxy are all included in
9598 // connect_start / connect_end. See
Eric Roman74103c72019-02-21 00:23:129599 // HttpNetworkTransaction::OnHttpsProxyTunnelResponseRedirect
Matt Menkeecfecfc72019-02-05 19:15:289600
9601 EXPECT_TRUE(load_timing_info.connect_timing.dns_start.is_null());
9602 EXPECT_TRUE(load_timing_info.connect_timing.dns_end.is_null());
9603 EXPECT_TRUE(load_timing_info.connect_timing.ssl_start.is_null());
9604 EXPECT_TRUE(load_timing_info.connect_timing.ssl_end.is_null());
9605
9606 EXPECT_EQ(start_time, load_timing_info.proxy_resolve_start);
9607 EXPECT_EQ(start_time, load_timing_info.proxy_resolve_end);
9608 EXPECT_EQ(start_time, load_timing_info.connect_timing.connect_start);
9609 EXPECT_EQ(start_time + 3 * kTimeIncrement,
9610 load_timing_info.connect_timing.connect_end);
[email protected]029c83b62013-01-24 05:28:209611
9612 EXPECT_TRUE(load_timing_info.send_start.is_null());
9613 EXPECT_TRUE(load_timing_info.send_end.is_null());
9614 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:299615}
9616
Eric Roman74103c72019-02-21 00:23:129617// Test that an HTTPS Proxy cannot redirect a CONNECT request for subresources.
9618TEST_F(HttpNetworkTransactionTest,
9619 RedirectOfHttpsConnectSubresourceViaHttpsProxy) {
9620 base::HistogramTester histograms;
9621 session_deps_.proxy_resolution_service =
9622 ProxyResolutionService::CreateFixedFromPacResult(
9623 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9624 TestNetLog net_log;
9625 session_deps_.net_log = &net_log;
9626
9627 HttpRequestInfo request;
9628 request.method = "GET";
9629 request.url = GURL("https://www.example.org/");
9630 request.traffic_annotation =
9631 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9632
9633 MockWrite data_writes[] = {
9634 MockWrite(ASYNC, 0,
9635 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9636 "Host: www.example.org:443\r\n"
9637 "Proxy-Connection: keep-alive\r\n\r\n"),
9638 };
9639
9640 MockRead data_reads[] = {
9641 MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
9642 MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
9643 MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
9644 };
9645
9646 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
9647 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9648
9649 session_deps_.socket_factory->AddSocketDataProvider(&data);
9650 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9651
9652 TestCompletionCallback callback;
9653
9654 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9655 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9656
9657 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9658 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9659
9660 rv = callback.WaitForResult();
9661 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
9662
9663 histograms.ExpectUniqueSample(
9664 "Net.Proxy.RedirectDuringConnect",
9665 HttpNetworkTransaction::kSubresourceByExplicitProxy, 1);
9666}
9667
9668// Test that an HTTPS Proxy which was auto-detected cannot redirect a CONNECT
9669// request for main frames.
9670TEST_F(HttpNetworkTransactionTest,
9671 RedirectOfHttpsConnectViaAutoDetectedHttpsProxy) {
9672 base::HistogramTester histograms;
9673 session_deps_.proxy_resolution_service =
9674 ProxyResolutionService::CreateFixedFromAutoDetectedPacResult(
9675 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9676 TestNetLog net_log;
9677 session_deps_.net_log = &net_log;
9678
9679 HttpRequestInfo request;
9680 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
9681 request.method = "GET";
9682 request.url = GURL("https://www.example.org/");
9683 request.traffic_annotation =
9684 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9685
9686 MockWrite data_writes[] = {
9687 MockWrite(ASYNC, 0,
9688 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9689 "Host: www.example.org:443\r\n"
9690 "Proxy-Connection: keep-alive\r\n\r\n"),
9691 };
9692
9693 MockRead data_reads[] = {
9694 MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
9695 MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
9696 MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
9697 };
9698
9699 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
9700 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9701
9702 session_deps_.socket_factory->AddSocketDataProvider(&data);
9703 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9704
9705 TestCompletionCallback callback;
9706
9707 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9708 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9709
9710 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9712
9713 rv = callback.WaitForResult();
9714 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
9715
9716 histograms.ExpectUniqueSample(
9717 "Net.Proxy.RedirectDuringConnect",
9718 HttpNetworkTransaction::kMainFrameByAutoDetectedProxy, 1);
9719}
9720
9721// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request for main
9722// frames.
bncd16676a2016-07-20 16:23:019723TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Eric Roman74103c72019-02-21 00:23:129724 base::HistogramTester histograms;
Ramin Halavatica8d5252018-03-12 05:33:499725 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9726 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeecfecfc72019-02-05 19:15:289727 TestNetLog net_log;
9728 session_deps_.net_log = &net_log;
9729
9730 base::TimeTicks start_time = base::TimeTicks::Now();
9731 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9732 session_deps_.host_resolver->set_ondemand_mode(true);
[email protected]511f6f52010-12-17 03:58:299733
9734 HttpRequestInfo request;
9735 request.method = "GET";
Eric Roman74103c72019-02-21 00:23:129736 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
bncce36dca22015-04-21 22:11:239737 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109738 request.traffic_annotation =
9739 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299740
Ryan Hamilton0239aac2018-05-19 00:03:139741 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049742 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9743 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139744 spdy::SpdySerializedFrame goaway(
9745 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299746 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419747 CreateMockWrite(conn, 0, SYNCHRONOUS),
Matt Menkeecfecfc72019-02-05 19:15:289748 CreateMockWrite(goaway, 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:299749 };
9750
9751 static const char* const kExtraHeaders[] = {
9752 "location",
9753 "http://login.example.com/",
9754 };
Ryan Hamilton0239aac2018-05-19 00:03:139755 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249756 "302", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:299757 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289758 // Pause on first read.
9759 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2),
9760 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299761 };
9762
Matt Menkeecfecfc72019-02-05 19:15:289763 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069764 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369765 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299766
[email protected]bb88e1d32013-05-03 23:11:079767 session_deps_.socket_factory->AddSocketDataProvider(&data);
9768 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299769
[email protected]49639fa2011-12-20 23:22:419770 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299771
danakj1fd259a02016-04-16 03:17:099772 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169773 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299774
tfarina42834112016-09-22 13:38:209775 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019776 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289777 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
[email protected]511f6f52010-12-17 03:58:299778
Matt Menkeecfecfc72019-02-05 19:15:289779 // Host resolution takes |kTimeIncrement|.
9780 FastForwardBy(kTimeIncrement);
9781 // Resolving the current request with |ResolveNow| will cause the pending
9782 // request to instantly complete, and the async connect will start as well.
9783 session_deps_.host_resolver->ResolveOnlyRequestNow();
9784
9785 // Connecting takes |kTimeIncrement|.
9786 FastForwardBy(kTimeIncrement);
9787 data.RunUntilPaused();
9788
9789 FastForwardBy(kTimeIncrement);
9790 data.Resume();
[email protected]511f6f52010-12-17 03:58:299791 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019792 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169793 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299794
wezca1070932016-05-26 20:30:529795 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299796
9797 EXPECT_EQ(302, response->headers->response_code());
9798 std::string url;
9799 EXPECT_TRUE(response->headers->IsRedirect(&url));
9800 EXPECT_EQ("http://login.example.com/", url);
Matt Menkeecfecfc72019-02-05 19:15:289801
9802 LoadTimingInfo load_timing_info;
9803 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
9804
9805 EXPECT_FALSE(load_timing_info.socket_reused);
9806 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
9807
9808 // No proxy resolution times, since there's no PAC script.
9809 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
9810 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
9811
9812 // In the case of redirects from proxies, just as with all responses from
9813 // proxies, DNS and SSL times reflect timing to look up the destination's
9814 // name, and negotiate an SSL connection to it (Neither of which are done in
9815 // this case), which the DNS and SSL times for the proxy are all included in
9816 // connect_start / connect_end. See
Eric Roman74103c72019-02-21 00:23:129817 // HttpNetworkTransaction::OnHttpsProxyTunnelResponseRedirect.
Matt Menkeecfecfc72019-02-05 19:15:289818
9819 EXPECT_TRUE(load_timing_info.connect_timing.dns_start.is_null());
9820 EXPECT_TRUE(load_timing_info.connect_timing.dns_end.is_null());
9821 EXPECT_TRUE(load_timing_info.connect_timing.ssl_start.is_null());
9822 EXPECT_TRUE(load_timing_info.connect_timing.ssl_end.is_null());
9823
9824 EXPECT_EQ(start_time, load_timing_info.connect_timing.connect_start);
9825 EXPECT_EQ(start_time + 3 * kTimeIncrement,
9826 load_timing_info.connect_timing.connect_end);
9827
9828 EXPECT_TRUE(load_timing_info.send_start.is_null());
9829 EXPECT_TRUE(load_timing_info.send_end.is_null());
9830 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
Eric Roman74103c72019-02-21 00:23:129831
9832 histograms.ExpectUniqueSample(
9833 "Net.Proxy.RedirectDuringConnect",
9834 HttpNetworkTransaction::kMainFrameByExplicitProxy, 1);
[email protected]511f6f52010-12-17 03:58:299835}
9836
[email protected]4eddbc732012-08-09 05:40:179837// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019838TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499839 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9840 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299841
9842 HttpRequestInfo request;
9843 request.method = "GET";
bncce36dca22015-04-21 22:11:239844 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109845 request.traffic_annotation =
9846 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299847
9848 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179849 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9850 "Host: www.example.org:443\r\n"
9851 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299852 };
9853
9854 MockRead data_reads[] = {
9855 MockRead("HTTP/1.1 404 Not Found\r\n"),
9856 MockRead("Content-Length: 23\r\n\r\n"),
9857 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:069858 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:299859 };
9860
Ryan Sleevib8d7ea02018-05-07 20:01:019861 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069862 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299863
[email protected]bb88e1d32013-05-03 23:11:079864 session_deps_.socket_factory->AddSocketDataProvider(&data);
9865 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299866
[email protected]49639fa2011-12-20 23:22:419867 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299868
danakj1fd259a02016-04-16 03:17:099869 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169870 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299871
tfarina42834112016-09-22 13:38:209872 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019873 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299874
9875 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019876 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299877
ttuttle960fcbf2016-04-19 13:26:329878 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299879}
9880
[email protected]4eddbc732012-08-09 05:40:179881// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019882TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499883 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9884 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299885
9886 HttpRequestInfo request;
9887 request.method = "GET";
bncce36dca22015-04-21 22:11:239888 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109889 request.traffic_annotation =
9890 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299891
Ryan Hamilton0239aac2018-05-19 00:03:139892 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049893 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9894 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139895 spdy::SpdySerializedFrame rst(
9896 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299897 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419898 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:299899 };
9900
9901 static const char* const kExtraHeaders[] = {
9902 "location",
9903 "http://login.example.com/",
9904 };
Ryan Hamilton0239aac2018-05-19 00:03:139905 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249906 "404", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:139907 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:199908 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:299909 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:419910 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:139911 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299912 };
9913
Ryan Sleevib8d7ea02018-05-07 20:01:019914 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069915 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369916 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299917
[email protected]bb88e1d32013-05-03 23:11:079918 session_deps_.socket_factory->AddSocketDataProvider(&data);
9919 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299920
[email protected]49639fa2011-12-20 23:22:419921 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299922
danakj1fd259a02016-04-16 03:17:099923 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169924 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299925
tfarina42834112016-09-22 13:38:209926 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019927 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299928
9929 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019930 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299931
ttuttle960fcbf2016-04-19 13:26:329932 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299933}
9934
[email protected]0c5fb722012-02-28 11:50:359935// Test the request-challenge-retry sequence for basic auth, through
9936// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:019937TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:359938 HttpRequestInfo request;
9939 request.method = "GET";
bncce36dca22015-04-21 22:11:239940 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:359941 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:299942 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:109943 request.traffic_annotation =
9944 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:359945
9946 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599947 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499948 ProxyResolutionService::CreateFixedFromPacResult(
9949 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519950 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079951 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:099952 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:359953
9954 // Since we have proxy, should try to establish tunnel.
Ryan Hamilton0239aac2018-05-19 00:03:139955 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049956 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9957 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139958 spdy::SpdySerializedFrame rst(
9959 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:389960 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:359961
bnc691fda62016-08-12 00:43:169962 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:359963 // be issuing -- the final header line contains the credentials.
9964 const char* const kAuthCredentials[] = {
9965 "proxy-authorization", "Basic Zm9vOmJhcg==",
9966 };
Ryan Hamilton0239aac2018-05-19 00:03:139967 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049968 kAuthCredentials, base::size(kAuthCredentials) / 2, 3,
9969 HttpProxyConnectJob::kH2QuicTunnelPriority,
bncce36dca22015-04-21 22:11:239970 HostPortPair("www.example.org", 443)));
9971 // fetch https://www.example.org/ via HTTP
9972 const char get[] =
9973 "GET / HTTP/1.1\r\n"
9974 "Host: www.example.org\r\n"
9975 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:139976 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:199977 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:359978
9979 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419980 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
9981 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:359982 };
9983
9984 // The proxy responds to the connect with a 407, using a persistent
9985 // connection.
thestig9d3bb0c2015-01-24 00:49:519986 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:359987 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:359988 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
9989 };
Ryan Hamilton0239aac2018-05-19 00:03:139990 spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249991 kAuthStatus, kAuthChallenge, base::size(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:359992
Ryan Hamilton0239aac2018-05-19 00:03:139993 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:359994 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
[email protected]0c5fb722012-02-28 11:50:359995 const char resp[] = "HTTP/1.1 200 OK\r\n"
9996 "Content-Length: 5\r\n\r\n";
9997
Ryan Hamilton0239aac2018-05-19 00:03:139998 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:199999 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:1310000 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:1910001 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:3510002 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110003 CreateMockRead(conn_auth_resp, 1, ASYNC),
10004 CreateMockRead(conn_resp, 4, ASYNC),
10005 CreateMockRead(wrapped_get_resp, 6, ASYNC),
10006 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:1310007 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:3510008 };
10009
Ryan Sleevib8d7ea02018-05-07 20:01:0110010 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710011 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:3510012 // Negotiate SPDY to the proxy
10013 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610014 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710015 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:3510016 // Vanilla SSL to the server
10017 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710018 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:3510019
10020 TestCompletionCallback callback1;
10021
bnc87dcefc2017-05-25 12:47:5810022 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910023 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:3510024
10025 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110026 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:3510027
10028 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110029 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4610030 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:3510031 log.GetEntries(&entries);
10032 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0010033 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
10034 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:3510035 ExpectLogContainsSomewhere(
10036 entries, pos,
mikecirone8b85c432016-09-08 19:11:0010037 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10038 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:3510039
10040 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210041 ASSERT_TRUE(response);
10042 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:3510043 EXPECT_EQ(407, response->headers->response_code());
10044 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:5210045 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:4310046 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:3510047
10048 TestCompletionCallback callback2;
10049
10050 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
10051 callback2.callback());
robpercival214763f2016-07-01 23:27:0110052 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:3510053
10054 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110055 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:3510056
10057 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210058 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:3510059
10060 EXPECT_TRUE(response->headers->IsKeepAlive());
10061 EXPECT_EQ(200, response->headers->response_code());
10062 EXPECT_EQ(5, response->headers->GetContentLength());
10063 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10064
10065 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:5210066 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:3510067
[email protected]029c83b62013-01-24 05:28:2010068 LoadTimingInfo load_timing_info;
10069 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10070 TestLoadTimingNotReusedWithPac(load_timing_info,
10071 CONNECT_TIMING_HAS_SSL_TIMES);
10072
[email protected]0c5fb722012-02-28 11:50:3510073 trans.reset();
10074 session->CloseAllConnections();
10075}
10076
[email protected]7c6f7ba2012-04-03 04:09:2910077// Test that an explicitly trusted SPDY proxy can push a resource from an
10078// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:0110079TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:1510080 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910081 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510082 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10083 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:2910084 HttpRequestInfo request;
10085 HttpRequestInfo push_request;
Ramin Halavatib5e433e2018-02-07 07:41:1010086 request.traffic_annotation =
10087 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:2910088
[email protected]7c6f7ba2012-04-03 04:09:2910089 request.method = "GET";
bncce36dca22015-04-21 22:11:2310090 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:2910091 push_request.method = "GET";
10092 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e2018-02-07 07:41:1010093 push_request.traffic_annotation =
10094 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:2910095
tbansal28e68f82016-02-04 02:56:1510096 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:5910097 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910098 ProxyResolutionService::CreateFixedFromPacResult(
10099 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110100 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710101 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010102
Eric Roman3d8546a2018-09-10 17:00:5210103 session_deps_.proxy_resolution_service->SetProxyDelegate(
10104 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010105
danakj1fd259a02016-04-16 03:17:0910106 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:2910107
Ryan Hamilton0239aac2018-05-19 00:03:1310108 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510109 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310110 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510111 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:2910112
10113 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110114 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510115 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:2910116 };
10117
Ryan Hamilton0239aac2018-05-19 00:03:1310118 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Raul Tambre94493c652019-03-11 17:18:3510119 nullptr, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
Bence Béky7bf94362018-01-10 13:19:3610120
Ryan Hamilton0239aac2018-05-19 00:03:1310121 spdy::SpdySerializedFrame stream1_reply(
Raul Tambre94493c652019-03-11 17:18:3510122 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:2910123
Ryan Hamilton0239aac2018-05-19 00:03:1310124 spdy::SpdySerializedFrame stream1_body(
10125 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:2910126
Ryan Hamilton0239aac2018-05-19 00:03:1310127 spdy::SpdySerializedFrame stream2_body(
Bence Békyd74f4382018-02-20 18:26:1910128 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:2910129
10130 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:3610131 CreateMockRead(stream2_syn, 1, ASYNC),
10132 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510133 CreateMockRead(stream1_body, 4, ASYNC),
10134 CreateMockRead(stream2_body, 5, ASYNC),
10135 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:2910136 };
10137
Ryan Sleevib8d7ea02018-05-07 20:01:0110138 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710139 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:2910140 // Negotiate SPDY to the proxy
10141 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610142 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710143 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:2910144
bnc87dcefc2017-05-25 12:47:5810145 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910146 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:2910147 TestCompletionCallback callback;
10148 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110149 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910150
10151 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110152 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910153 const HttpResponseInfo* response = trans->GetResponseInfo();
10154
bnc87dcefc2017-05-25 12:47:5810155 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:1910156 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:5010157 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910159
10160 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110161 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910162 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
10163
wezca1070932016-05-26 20:30:5210164 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:2910165 EXPECT_TRUE(response->headers->IsKeepAlive());
10166
10167 EXPECT_EQ(200, response->headers->response_code());
10168 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10169
10170 std::string response_data;
10171 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110172 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910173 EXPECT_EQ("hello!", response_data);
10174
[email protected]029c83b62013-01-24 05:28:2010175 LoadTimingInfo load_timing_info;
10176 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10177 TestLoadTimingNotReusedWithPac(load_timing_info,
10178 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10179
[email protected]7c6f7ba2012-04-03 04:09:2910180 // Verify the pushed stream.
wezca1070932016-05-26 20:30:5210181 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:2910182 EXPECT_EQ(200, push_response->headers->response_code());
10183
10184 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110185 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910186 EXPECT_EQ("pushed", response_data);
10187
[email protected]029c83b62013-01-24 05:28:2010188 LoadTimingInfo push_load_timing_info;
10189 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
10190 TestLoadTimingReusedWithPac(push_load_timing_info);
10191 // The transactions should share a socket ID, despite being for different
10192 // origins.
10193 EXPECT_EQ(load_timing_info.socket_log_id,
10194 push_load_timing_info.socket_log_id);
10195
[email protected]7c6f7ba2012-04-03 04:09:2910196 trans.reset();
10197 push_trans.reset();
10198 session->CloseAllConnections();
10199}
10200
[email protected]8c843192012-04-05 07:15:0010201// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:0110202TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510203 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910204 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510205 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10206 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:0010207 HttpRequestInfo request;
10208
10209 request.method = "GET";
bncce36dca22015-04-21 22:11:2310210 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010211 request.traffic_annotation =
10212 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:0010213
Ramin Halavatica8d5252018-03-12 05:33:4910214 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10215 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110216 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710217 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010218
10219 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210220 session_deps_.proxy_resolution_service->SetProxyDelegate(
10221 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010222
danakj1fd259a02016-04-16 03:17:0910223 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:0010224
Ryan Hamilton0239aac2018-05-19 00:03:1310225 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510226 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:0010227
Ryan Hamilton0239aac2018-05-19 00:03:1310228 spdy::SpdySerializedFrame push_rst(
10229 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:0010230
10231 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110232 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:0010233 };
10234
Ryan Hamilton0239aac2018-05-19 00:03:1310235 spdy::SpdySerializedFrame stream1_reply(
Raul Tambre94493c652019-03-11 17:18:3510236 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]8c843192012-04-05 07:15:0010237
Ryan Hamilton0239aac2018-05-19 00:03:1310238 spdy::SpdySerializedFrame stream1_body(
10239 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:0010240
Ryan Hamilton0239aac2018-05-19 00:03:1310241 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Raul Tambre94493c652019-03-11 17:18:3510242 nullptr, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:0010243
10244 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110245 CreateMockRead(stream1_reply, 1, ASYNC),
10246 CreateMockRead(stream2_syn, 2, ASYNC),
10247 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:5910248 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:0010249 };
10250
Ryan Sleevib8d7ea02018-05-07 20:01:0110251 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710252 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:0010253 // Negotiate SPDY to the proxy
10254 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610255 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710256 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:0010257
bnc87dcefc2017-05-25 12:47:5810258 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910259 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:0010260 TestCompletionCallback callback;
10261 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110262 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:0010263
10264 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110265 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010266 const HttpResponseInfo* response = trans->GetResponseInfo();
10267
wezca1070932016-05-26 20:30:5210268 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:0010269 EXPECT_TRUE(response->headers->IsKeepAlive());
10270
10271 EXPECT_EQ(200, response->headers->response_code());
10272 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10273
10274 std::string response_data;
10275 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110276 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010277 EXPECT_EQ("hello!", response_data);
10278
10279 trans.reset();
10280 session->CloseAllConnections();
10281}
10282
tbansal8ef1d3e2016-02-03 04:05:4210283// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
10284// resources.
bncd16676a2016-07-20 16:23:0110285TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510286 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910287 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510288 proxy_delegate->set_trusted_spdy_proxy(
10289 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
10290
tbansal8ef1d3e2016-02-03 04:05:4210291 HttpRequestInfo request;
10292
10293 request.method = "GET";
10294 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010295 request.traffic_annotation =
10296 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210297
10298 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:4910299 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10300 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210301 BoundTestNetLog log;
10302 session_deps_.net_log = log.bound().net_log();
10303
10304 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210305 session_deps_.proxy_resolution_service->SetProxyDelegate(
10306 proxy_delegate.get());
tbansal8ef1d3e2016-02-03 04:05:4210307
danakj1fd259a02016-04-16 03:17:0910308 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:4210309
Ryan Hamilton0239aac2018-05-19 00:03:1310310 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510311 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310312 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510313 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:4210314
10315 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110316 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510317 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:4210318 };
10319
Ryan Hamilton0239aac2018-05-19 00:03:1310320 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:1510321 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210322
Ryan Hamilton0239aac2018-05-19 00:03:1310323 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:3310324 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:4910325
Ryan Hamilton0239aac2018-05-19 00:03:1310326 spdy::SpdySerializedFrame stream1_body(
10327 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210328
Ryan Hamilton0239aac2018-05-19 00:03:1310329 spdy::SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:1510330 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210331
Ryan Hamilton0239aac2018-05-19 00:03:1310332 spdy::SpdySerializedFrame stream2_body(
10333 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210334
10335 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110336 CreateMockRead(stream1_reply, 1, ASYNC),
10337 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510338 CreateMockRead(stream1_body, 4, ASYNC),
10339 CreateMockRead(stream2_body, 5, ASYNC),
10340 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:4210341 };
10342
Ryan Sleevib8d7ea02018-05-07 20:01:0110343 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
tbansal8ef1d3e2016-02-03 04:05:4210344 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10345 // Negotiate SPDY to the proxy
10346 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610347 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:4210348 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
10349
bnc87dcefc2017-05-25 12:47:5810350 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910351 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:4210352 TestCompletionCallback callback;
10353 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110354 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:4210355
10356 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110357 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210358 const HttpResponseInfo* response = trans->GetResponseInfo();
10359
wezca1070932016-05-26 20:30:5210360 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:4210361 EXPECT_TRUE(response->headers->IsKeepAlive());
10362
10363 EXPECT_EQ(200, response->headers->response_code());
10364 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10365
10366 std::string response_data;
10367 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110368 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210369 EXPECT_EQ("hello!", response_data);
10370
10371 trans.reset();
10372 session->CloseAllConnections();
10373}
10374
[email protected]2df19bb2010-08-25 20:13:4610375// Test HTTPS connections to a site with a bad certificate, going through an
10376// HTTPS proxy
bncd16676a2016-07-20 16:23:0110377TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:4910378 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10379 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610380
10381 HttpRequestInfo request;
10382 request.method = "GET";
bncce36dca22015-04-21 22:11:2310383 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010384 request.traffic_annotation =
10385 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610386
10387 // Attempt to fetch the URL from a server with a bad cert
10388 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710389 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10390 "Host: www.example.org:443\r\n"
10391 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610392 };
10393
10394 MockRead bad_cert_reads[] = {
10395 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610396 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:4610397 };
10398
10399 // Attempt to fetch the URL with a good cert
10400 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710401 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10402 "Host: www.example.org:443\r\n"
10403 "Proxy-Connection: keep-alive\r\n\r\n"),
10404 MockWrite("GET / HTTP/1.1\r\n"
10405 "Host: www.example.org\r\n"
10406 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610407 };
10408
10409 MockRead good_cert_reads[] = {
10410 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
10411 MockRead("HTTP/1.0 200 OK\r\n"),
10412 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10413 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610414 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:4610415 };
10416
Ryan Sleevib8d7ea02018-05-07 20:01:0110417 StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
10418 StaticSocketDataProvider data(good_cert_reads, good_data_writes);
[email protected]8ddf8322012-02-23 18:08:0610419 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
10420 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:4610421
10422 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:0710423 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10424 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
10425 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:4610426
10427 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:0710428 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10429 session_deps_.socket_factory->AddSocketDataProvider(&data);
10430 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:4610431
[email protected]49639fa2011-12-20 23:22:4110432 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:4610433
danakj1fd259a02016-04-16 03:17:0910434 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610435 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:4610436
tfarina42834112016-09-22 13:38:2010437 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110438 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610439
10440 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110441 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:4610442
bnc691fda62016-08-12 00:43:1610443 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:0110444 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610445
10446 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110447 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:4610448
bnc691fda62016-08-12 00:43:1610449 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:4610450
wezca1070932016-05-26 20:30:5210451 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:4610452 EXPECT_EQ(100, response->headers->GetContentLength());
10453}
10454
bncd16676a2016-07-20 16:23:0110455TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:4210456 HttpRequestInfo request;
10457 request.method = "GET";
bncce36dca22015-04-21 22:11:2310458 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310459 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10460 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:1010461 request.traffic_annotation =
10462 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210463
danakj1fd259a02016-04-16 03:17:0910464 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610465 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710466
[email protected]1c773ea12009-04-28 19:58:4210467 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310468 MockWrite(
10469 "GET / HTTP/1.1\r\n"
10470 "Host: www.example.org\r\n"
10471 "Connection: keep-alive\r\n"
10472 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210473 };
10474
10475 // Lastly, the server responds with the actual content.
10476 MockRead data_reads[] = {
10477 MockRead("HTTP/1.0 200 OK\r\n"),
10478 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10479 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610480 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210481 };
10482
Ryan Sleevib8d7ea02018-05-07 20:01:0110483 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710484 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210485
[email protected]49639fa2011-12-20 23:22:4110486 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210487
tfarina42834112016-09-22 13:38:2010488 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210490
10491 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110492 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210493}
10494
bncd16676a2016-07-20 16:23:0110495TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
Matt Menked732ea42019-03-08 12:05:0010496 // Test user agent values, used both for the request header of the original
10497 // request, and the value returned by the HttpUserAgentSettings. nullptr means
10498 // no request header / no HttpUserAgentSettings object.
10499 const char* kTestUserAgents[] = {nullptr, "", "Foopy"};
[email protected]da81f132010-08-18 23:39:2910500
Matt Menked732ea42019-03-08 12:05:0010501 for (const char* setting_user_agent : kTestUserAgents) {
10502 if (!setting_user_agent) {
10503 session_deps_.http_user_agent_settings.reset();
10504 } else {
10505 session_deps_.http_user_agent_settings =
10506 std::make_unique<StaticHttpUserAgentSettings>(
10507 std::string() /* accept-language */, setting_user_agent);
10508 }
10509 session_deps_.proxy_resolution_service =
10510 ProxyResolutionService::CreateFixed("myproxy:70",
10511 TRAFFIC_ANNOTATION_FOR_TESTS);
10512 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10513 for (const char* request_user_agent : kTestUserAgents) {
10514 HttpRequestInfo request;
10515 request.method = "GET";
10516 request.url = GURL("https://www.example.org/");
10517 if (request_user_agent) {
10518 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10519 request_user_agent);
10520 }
10521 request.traffic_annotation =
10522 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710523
Matt Menked732ea42019-03-08 12:05:0010524 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]da81f132010-08-18 23:39:2910525
Matt Menked732ea42019-03-08 12:05:0010526 std::string expected_request;
10527 if (!setting_user_agent || strlen(setting_user_agent) == 0) {
10528 expected_request =
10529 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10530 "Host: www.example.org:443\r\n"
10531 "Proxy-Connection: keep-alive\r\n\r\n";
10532 } else {
10533 expected_request = base::StringPrintf(
10534 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10535 "Host: www.example.org:443\r\n"
10536 "Proxy-Connection: keep-alive\r\n"
10537 "User-Agent: %s\r\n\r\n",
10538 setting_user_agent);
10539 }
10540 MockWrite data_writes[] = {
10541 MockWrite(expected_request.c_str()),
10542 };
10543 MockRead data_reads[] = {
10544 // Return an error, so the transaction stops here (this test isn't
10545 // interested in the rest).
10546 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
10547 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10548 MockRead("Proxy-Connection: close\r\n\r\n"),
10549 };
[email protected]da81f132010-08-18 23:39:2910550
Matt Menked732ea42019-03-08 12:05:0010551 StaticSocketDataProvider data(data_reads, data_writes);
10552 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:2910553
Matt Menked732ea42019-03-08 12:05:0010554 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:2910555
Matt Menked732ea42019-03-08 12:05:0010556 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10557 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10558
10559 rv = callback.WaitForResult();
10560 EXPECT_THAT(rv, IsOk());
10561 }
10562 }
[email protected]da81f132010-08-18 23:39:2910563}
10564
bncd16676a2016-07-20 16:23:0110565TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:4210566 HttpRequestInfo request;
10567 request.method = "GET";
bncce36dca22015-04-21 22:11:2310568 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:1610569 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
10570 "http://the.previous.site.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010571 request.traffic_annotation =
10572 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210573
danakj1fd259a02016-04-16 03:17:0910574 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610575 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710576
[email protected]1c773ea12009-04-28 19:58:4210577 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310578 MockWrite(
10579 "GET / HTTP/1.1\r\n"
10580 "Host: www.example.org\r\n"
10581 "Connection: keep-alive\r\n"
10582 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210583 };
10584
10585 // Lastly, the server responds with the actual content.
10586 MockRead data_reads[] = {
10587 MockRead("HTTP/1.0 200 OK\r\n"),
10588 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10589 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610590 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210591 };
10592
Ryan Sleevib8d7ea02018-05-07 20:01:0110593 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710594 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210595
[email protected]49639fa2011-12-20 23:22:4110596 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210597
tfarina42834112016-09-22 13:38:2010598 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110599 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210600
10601 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110602 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210603}
10604
bncd16676a2016-07-20 16:23:0110605TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210606 HttpRequestInfo request;
10607 request.method = "POST";
bncce36dca22015-04-21 22:11:2310608 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010609 request.traffic_annotation =
10610 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210611
danakj1fd259a02016-04-16 03:17:0910612 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610613 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710614
[email protected]1c773ea12009-04-28 19:58:4210615 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310616 MockWrite(
10617 "POST / HTTP/1.1\r\n"
10618 "Host: www.example.org\r\n"
10619 "Connection: keep-alive\r\n"
10620 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210621 };
10622
10623 // Lastly, the server responds with the actual content.
10624 MockRead data_reads[] = {
10625 MockRead("HTTP/1.0 200 OK\r\n"),
10626 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10627 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610628 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210629 };
10630
Ryan Sleevib8d7ea02018-05-07 20:01:0110631 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710632 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210633
[email protected]49639fa2011-12-20 23:22:4110634 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210635
tfarina42834112016-09-22 13:38:2010636 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110637 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210638
10639 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110640 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210641}
10642
bncd16676a2016-07-20 16:23:0110643TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210644 HttpRequestInfo request;
10645 request.method = "PUT";
bncce36dca22015-04-21 22:11:2310646 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010647 request.traffic_annotation =
10648 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210649
danakj1fd259a02016-04-16 03:17:0910650 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610651 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710652
[email protected]1c773ea12009-04-28 19:58:4210653 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310654 MockWrite(
10655 "PUT / HTTP/1.1\r\n"
10656 "Host: www.example.org\r\n"
10657 "Connection: keep-alive\r\n"
10658 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210659 };
10660
10661 // Lastly, the server responds with the actual content.
10662 MockRead data_reads[] = {
10663 MockRead("HTTP/1.0 200 OK\r\n"),
10664 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10665 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610666 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210667 };
10668
Ryan Sleevib8d7ea02018-05-07 20:01:0110669 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710670 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210671
[email protected]49639fa2011-12-20 23:22:4110672 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210673
tfarina42834112016-09-22 13:38:2010674 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110675 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210676
10677 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110678 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210679}
10680
bncd16676a2016-07-20 16:23:0110681TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210682 HttpRequestInfo request;
10683 request.method = "HEAD";
bncce36dca22015-04-21 22:11:2310684 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010685 request.traffic_annotation =
10686 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210687
danakj1fd259a02016-04-16 03:17:0910688 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610689 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710690
[email protected]1c773ea12009-04-28 19:58:4210691 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:1310692 MockWrite("HEAD / HTTP/1.1\r\n"
10693 "Host: www.example.org\r\n"
10694 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210695 };
10696
10697 // Lastly, the server responds with the actual content.
10698 MockRead data_reads[] = {
10699 MockRead("HTTP/1.0 200 OK\r\n"),
10700 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10701 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610702 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210703 };
10704
Ryan Sleevib8d7ea02018-05-07 20:01:0110705 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710706 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210707
[email protected]49639fa2011-12-20 23:22:4110708 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210709
tfarina42834112016-09-22 13:38:2010710 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210712
10713 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110714 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210715}
10716
bncd16676a2016-07-20 16:23:0110717TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:4210718 HttpRequestInfo request;
10719 request.method = "GET";
bncce36dca22015-04-21 22:11:2310720 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210721 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:1010722 request.traffic_annotation =
10723 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210724
danakj1fd259a02016-04-16 03:17:0910725 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610726 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710727
[email protected]1c773ea12009-04-28 19:58:4210728 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310729 MockWrite(
10730 "GET / HTTP/1.1\r\n"
10731 "Host: www.example.org\r\n"
10732 "Connection: keep-alive\r\n"
10733 "Pragma: no-cache\r\n"
10734 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210735 };
10736
10737 // Lastly, the server responds with the actual content.
10738 MockRead data_reads[] = {
10739 MockRead("HTTP/1.0 200 OK\r\n"),
10740 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10741 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610742 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210743 };
10744
Ryan Sleevib8d7ea02018-05-07 20:01:0110745 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710746 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210747
[email protected]49639fa2011-12-20 23:22:4110748 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210749
tfarina42834112016-09-22 13:38:2010750 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110751 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210752
10753 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110754 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210755}
10756
bncd16676a2016-07-20 16:23:0110757TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:4210758 HttpRequestInfo request;
10759 request.method = "GET";
bncce36dca22015-04-21 22:11:2310760 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210761 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:1010762 request.traffic_annotation =
10763 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210764
danakj1fd259a02016-04-16 03:17:0910765 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610766 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710767
[email protected]1c773ea12009-04-28 19:58:4210768 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310769 MockWrite(
10770 "GET / HTTP/1.1\r\n"
10771 "Host: www.example.org\r\n"
10772 "Connection: keep-alive\r\n"
10773 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210774 };
10775
10776 // Lastly, the server responds with the actual content.
10777 MockRead data_reads[] = {
10778 MockRead("HTTP/1.0 200 OK\r\n"),
10779 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10780 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610781 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210782 };
10783
Ryan Sleevib8d7ea02018-05-07 20:01:0110784 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710785 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210786
[email protected]49639fa2011-12-20 23:22:4110787 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210788
tfarina42834112016-09-22 13:38:2010789 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110790 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210791
10792 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110793 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210794}
10795
bncd16676a2016-07-20 16:23:0110796TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:4210797 HttpRequestInfo request;
10798 request.method = "GET";
bncce36dca22015-04-21 22:11:2310799 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310800 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e2018-02-07 07:41:1010801 request.traffic_annotation =
10802 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210803
danakj1fd259a02016-04-16 03:17:0910804 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610805 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710806
[email protected]1c773ea12009-04-28 19:58:4210807 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310808 MockWrite(
10809 "GET / HTTP/1.1\r\n"
10810 "Host: www.example.org\r\n"
10811 "Connection: keep-alive\r\n"
10812 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210813 };
10814
10815 // Lastly, the server responds with the actual content.
10816 MockRead data_reads[] = {
10817 MockRead("HTTP/1.0 200 OK\r\n"),
10818 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10819 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610820 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210821 };
10822
Ryan Sleevib8d7ea02018-05-07 20:01:0110823 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710824 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210825
[email protected]49639fa2011-12-20 23:22:4110826 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210827
tfarina42834112016-09-22 13:38:2010828 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110829 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210830
10831 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110832 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210833}
10834
bncd16676a2016-07-20 16:23:0110835TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:4710836 HttpRequestInfo request;
10837 request.method = "GET";
bncce36dca22015-04-21 22:11:2310838 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310839 request.extra_headers.SetHeader("referer", "www.foo.com");
10840 request.extra_headers.SetHeader("hEllo", "Kitty");
10841 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1010842 request.traffic_annotation =
10843 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:4710844
danakj1fd259a02016-04-16 03:17:0910845 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610846 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710847
[email protected]270c6412010-03-29 22:02:4710848 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310849 MockWrite(
10850 "GET / HTTP/1.1\r\n"
10851 "Host: www.example.org\r\n"
10852 "Connection: keep-alive\r\n"
10853 "referer: www.foo.com\r\n"
10854 "hEllo: Kitty\r\n"
10855 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:4710856 };
10857
10858 // Lastly, the server responds with the actual content.
10859 MockRead data_reads[] = {
10860 MockRead("HTTP/1.0 200 OK\r\n"),
10861 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10862 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610863 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:4710864 };
10865
Ryan Sleevib8d7ea02018-05-07 20:01:0110866 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710867 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:4710868
[email protected]49639fa2011-12-20 23:22:4110869 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:4710870
tfarina42834112016-09-22 13:38:2010871 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110872 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:4710873
10874 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110875 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:4710876}
10877
bncd16676a2016-07-20 16:23:0110878TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710879 HttpRequestInfo request;
10880 request.method = "GET";
bncce36dca22015-04-21 22:11:2310881 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010882 request.traffic_annotation =
10883 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710884
Lily Houghton8c2f97d2018-01-22 05:06:5910885 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910886 ProxyResolutionService::CreateFixedFromPacResult(
10887 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110888 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710889 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210890
danakj1fd259a02016-04-16 03:17:0910891 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610892 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210893
[email protected]3cd17242009-06-23 02:59:0210894 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10895 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10896
10897 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410898 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10899 MockWrite("GET / HTTP/1.1\r\n"
10900 "Host: www.example.org\r\n"
10901 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210902
10903 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410904 MockRead(ASYNC, read_buffer, 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]3cd17242009-06-23 02:59:0210908
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]3cd17242009-06-23 02:59:0210911
[email protected]49639fa2011-12-20 23:22:4110912 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210913
tfarina42834112016-09-22 13:38:2010914 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110915 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210916
10917 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110918 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210919
bnc691fda62016-08-12 00:43:1610920 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210921 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:0210922
tbansal2ecbbc72016-10-06 17:15:4710923 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:2010924 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610925 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010926 TestLoadTimingNotReusedWithPac(load_timing_info,
10927 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10928
[email protected]3cd17242009-06-23 02:59:0210929 std::string response_text;
bnc691fda62016-08-12 00:43:1610930 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110931 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210932 EXPECT_EQ("Payload", response_text);
10933}
10934
bncd16676a2016-07-20 16:23:0110935TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710936 HttpRequestInfo request;
10937 request.method = "GET";
bncce36dca22015-04-21 22:11:2310938 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010939 request.traffic_annotation =
10940 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710941
Lily Houghton8c2f97d2018-01-22 05:06:5910942 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910943 ProxyResolutionService::CreateFixedFromPacResult(
10944 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110945 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710946 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210947
danakj1fd259a02016-04-16 03:17:0910948 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610949 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210950
[email protected]3cd17242009-06-23 02:59:0210951 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
10952 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10953
10954 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310955 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
Avi Drissman4365a4782018-12-28 19:26:2410956 base::size(write_buffer)),
10957 MockWrite("GET / HTTP/1.1\r\n"
10958 "Host: www.example.org\r\n"
10959 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210960
10961 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410962 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
10963 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]e0c27be2009-07-15 13:09:3510967
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]e0c27be2009-07-15 13:09:3510970
[email protected]8ddf8322012-02-23 18:08:0610971 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710972 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:3510973
[email protected]49639fa2011-12-20 23:22:4110974 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510975
tfarina42834112016-09-22 13:38:2010976 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110977 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510978
10979 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110980 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510981
[email protected]029c83b62013-01-24 05:28:2010982 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 TestLoadTimingNotReusedWithPac(load_timing_info,
10985 CONNECT_TIMING_HAS_SSL_TIMES);
10986
bnc691fda62016-08-12 00:43:1610987 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210988 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710989 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510990
10991 std::string response_text;
bnc691fda62016-08-12 00:43:1610992 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110993 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510994 EXPECT_EQ("Payload", response_text);
10995}
10996
bncd16676a2016-07-20 16:23:0110997TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:2010998 HttpRequestInfo request;
10999 request.method = "GET";
bncce36dca22015-04-21 22:11:2311000 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011001 request.traffic_annotation =
11002 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:2011003
Ramin Halavatica8d5252018-03-12 05:33:4911004 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11005 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111006 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711007 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:2011008
danakj1fd259a02016-04-16 03:17:0911009 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611010 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:2011011
11012 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
11013 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
11014
11015 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411016 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
11017 MockWrite("GET / HTTP/1.1\r\n"
11018 "Host: www.example.org\r\n"
11019 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:2011020
11021 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411022 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
11023 MockRead("HTTP/1.0 200 OK\r\n"),
11024 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11025 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]029c83b62013-01-24 05:28:2011026
Ryan Sleevib8d7ea02018-05-07 20:01:0111027 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711028 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:2011029
11030 TestCompletionCallback callback;
11031
tfarina42834112016-09-22 13:38:2011032 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111033 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:2011034
11035 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111036 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2011037
bnc691fda62016-08-12 00:43:1611038 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211039 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:2011040
11041 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611042 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011043 TestLoadTimingNotReused(load_timing_info,
11044 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
11045
11046 std::string response_text;
bnc691fda62016-08-12 00:43:1611047 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111048 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2011049 EXPECT_EQ("Payload", response_text);
11050}
11051
bncd16676a2016-07-20 16:23:0111052TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2711053 HttpRequestInfo request;
11054 request.method = "GET";
bncce36dca22015-04-21 22:11:2311055 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011056 request.traffic_annotation =
11057 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711058
Lily Houghton8c2f97d2018-01-22 05:06:5911059 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911060 ProxyResolutionService::CreateFixedFromPacResult(
11061 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111062 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711063 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3511064
danakj1fd259a02016-04-16 03:17:0911065 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611066 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3511067
[email protected]e0c27be2009-07-15 13:09:3511068 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
11069 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3711070 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2311071 0x05, // Version
11072 0x01, // Command (CONNECT)
11073 0x00, // Reserved.
11074 0x03, // Address type (DOMAINNAME).
11075 0x0F, // Length of domain (15)
11076 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
11077 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3711078 };
[email protected]e0c27be2009-07-15 13:09:3511079 const char kSOCKS5OkResponse[] =
11080 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
11081
11082 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411083 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
11084 MockWrite(ASYNC, kSOCKS5OkRequest, base::size(kSOCKS5OkRequest)),
11085 MockWrite("GET / HTTP/1.1\r\n"
11086 "Host: www.example.org\r\n"
11087 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3511088
11089 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411090 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11091 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11092 MockRead("HTTP/1.0 200 OK\r\n"),
11093 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11094 MockRead("Payload"),
11095 MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3511096
Ryan Sleevib8d7ea02018-05-07 20:01:0111097 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711098 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3511099
[email protected]49639fa2011-12-20 23:22:4111100 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3511101
tfarina42834112016-09-22 13:38:2011102 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111103 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3511104
11105 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111106 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3511107
bnc691fda62016-08-12 00:43:1611108 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211109 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711110 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3511111
[email protected]029c83b62013-01-24 05:28:2011112 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611113 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011114 TestLoadTimingNotReusedWithPac(load_timing_info,
11115 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
11116
[email protected]e0c27be2009-07-15 13:09:3511117 std::string response_text;
bnc691fda62016-08-12 00:43:1611118 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111119 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3511120 EXPECT_EQ("Payload", response_text);
11121}
11122
bncd16676a2016-07-20 16:23:0111123TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2711124 HttpRequestInfo request;
11125 request.method = "GET";
bncce36dca22015-04-21 22:11:2311126 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011127 request.traffic_annotation =
11128 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711129
Lily Houghton8c2f97d2018-01-22 05:06:5911130 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911131 ProxyResolutionService::CreateFixedFromPacResult(
11132 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111133 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711134 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3511135
danakj1fd259a02016-04-16 03:17:0911136 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611137 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3511138
[email protected]e0c27be2009-07-15 13:09:3511139 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
11140 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3711141 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2311142 0x05, // Version
11143 0x01, // Command (CONNECT)
11144 0x00, // Reserved.
11145 0x03, // Address type (DOMAINNAME).
11146 0x0F, // Length of domain (15)
11147 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
11148 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3711149 };
11150
[email protected]e0c27be2009-07-15 13:09:3511151 const char kSOCKS5OkResponse[] =
11152 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
11153
11154 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411155 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
bncce36dca22015-04-21 22:11:2311156 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
Avi Drissman4365a4782018-12-28 19:26:2411157 base::size(kSOCKS5OkRequest)),
11158 MockWrite("GET / HTTP/1.1\r\n"
11159 "Host: www.example.org\r\n"
11160 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3511161
11162 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411163 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11164 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11165 MockRead("HTTP/1.0 200 OK\r\n"),
11166 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11167 MockRead("Payload"),
11168 MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0211169
Ryan Sleevib8d7ea02018-05-07 20:01:0111170 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711171 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0211172
[email protected]8ddf8322012-02-23 18:08:0611173 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711174 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0211175
[email protected]49639fa2011-12-20 23:22:4111176 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0211177
tfarina42834112016-09-22 13:38:2011178 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111179 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0211180
11181 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111182 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211183
bnc691fda62016-08-12 00:43:1611184 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211185 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711186 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0211187
[email protected]029c83b62013-01-24 05:28:2011188 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611189 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011190 TestLoadTimingNotReusedWithPac(load_timing_info,
11191 CONNECT_TIMING_HAS_SSL_TIMES);
11192
[email protected]3cd17242009-06-23 02:59:0211193 std::string response_text;
bnc691fda62016-08-12 00:43:1611194 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111195 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211196 EXPECT_EQ("Payload", response_text);
11197}
11198
[email protected]448d4ca52012-03-04 04:12:2311199namespace {
11200
Matt Menkef6edce752019-03-19 17:21:5611201// Tests that for connection endpoints the group ids are correctly set.
[email protected]2d731a32010-04-29 01:04:0611202
Matt Menkef6edce752019-03-19 17:21:5611203struct GroupIdTest {
[email protected]2d731a32010-04-29 01:04:0611204 std::string proxy_server;
11205 std::string url;
Matt Menkef6edce752019-03-19 17:21:5611206 ClientSocketPool::GroupId expected_group_id;
[email protected]e60e47a2010-07-14 03:37:1811207 bool ssl;
[email protected]2d731a32010-04-29 01:04:0611208};
11209
Matt Menkef6edce752019-03-19 17:21:5611210std::unique_ptr<HttpNetworkSession> SetupSessionForGroupIdTests(
[email protected]bb88e1d32013-05-03 23:11:0711211 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0911212 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0611213
bnc525e175a2016-06-20 12:36:4011214 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311215 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111216 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1211217 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111218 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4211219 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4611220 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0611221
11222 return session;
11223}
11224
Matt Menkef6edce752019-03-19 17:21:5611225int GroupIdTransactionHelper(const std::string& url,
11226 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0611227 HttpRequestInfo request;
11228 request.method = "GET";
11229 request.url = GURL(url);
Ramin Halavatib5e433e2018-02-07 07:41:1011230 request.traffic_annotation =
11231 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0611232
bnc691fda62016-08-12 00:43:1611233 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2711234
[email protected]49639fa2011-12-20 23:22:4111235 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0611236
11237 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2011238 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0611239}
11240
[email protected]448d4ca52012-03-04 04:12:2311241} // namespace
11242
Matt Menkef6edce752019-03-19 17:21:5611243TEST_F(HttpNetworkTransactionTest, GroupIdForDirectConnections) {
11244 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311245 {
Matt Menkef6edce752019-03-19 17:21:5611246 "", // unused
11247 "http://www.example.org/direct",
11248 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11249 ClientSocketPool::SocketType::kHttp,
11250 false /* privacy_mode */),
11251 false,
bncce36dca22015-04-21 22:11:2311252 },
11253 {
Matt Menkef6edce752019-03-19 17:21:5611254 "", // unused
11255 "http://[2001:1418:13:1::25]/direct",
11256 ClientSocketPool::GroupId(HostPortPair("2001:1418:13:1::25", 80),
11257 ClientSocketPool::SocketType::kHttp,
11258 false /* privacy_mode */),
11259 false,
bncce36dca22015-04-21 22:11:2311260 },
[email protected]04e5be32009-06-26 20:00:3111261
bncce36dca22015-04-21 22:11:2311262 // SSL Tests
11263 {
Matt Menkef6edce752019-03-19 17:21:5611264 "", // unused
11265 "https://www.example.org/direct_ssl",
11266 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11267 ClientSocketPool::SocketType::kSsl,
11268 false /* privacy_mode */),
11269 true,
bncce36dca22015-04-21 22:11:2311270 },
11271 {
Matt Menkef6edce752019-03-19 17:21:5611272 "", // unused
11273 "https://[2001:1418:13:1::25]/direct",
11274 ClientSocketPool::GroupId(HostPortPair("2001:1418:13:1::25", 443),
11275 ClientSocketPool::SocketType::kSsl,
11276 false /* privacy_mode */),
11277 true,
bncce36dca22015-04-21 22:11:2311278 },
11279 {
Matt Menkef6edce752019-03-19 17:21:5611280 "", // unused
11281 "https://host.with.alternate/direct",
11282 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11283 ClientSocketPool::SocketType::kSsl,
11284 false /* privacy_mode */),
11285 true,
bncce36dca22015-04-21 22:11:2311286 },
[email protected]2d731a32010-04-29 01:04:0611287 };
[email protected]2ff8b312010-04-26 22:20:5411288
Avi Drissman4365a4782018-12-28 19:26:2411289 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911290 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911291 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11292 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911293 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611294 SetupSessionForGroupIdTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611295
mmenkee65e7af2015-10-13 17:16:4211296 HttpNetworkSessionPeer peer(session.get());
Matt Menkef6edce752019-03-19 17:21:5611297 CaptureGroupIdTransportSocketPool* transport_conn_pool =
Matt Menked6fd2a52019-03-20 06:14:3611298 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911299 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011300 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
11301 base::WrapUnique(transport_conn_pool));
dchengc7eeda422015-12-26 03:56:4811302 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611303
11304 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611305 GroupIdTransactionHelper(tests[i].url, session.get()));
11306 EXPECT_EQ(tests[i].expected_group_id,
11307 transport_conn_pool->last_group_id_received());
Matt Menke9d5e2c92019-02-05 01:42:2311308 EXPECT_TRUE(transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0611309 }
[email protected]2d731a32010-04-29 01:04:0611310}
11311
Matt Menkef6edce752019-03-19 17:21:5611312TEST_F(HttpNetworkTransactionTest, GroupIdForHTTPProxyConnections) {
11313 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311314 {
Matt Menke4802de62019-03-08 22:47:5011315 "http_proxy",
11316 "http://www.example.org/http_proxy_normal",
Matt Menkef6edce752019-03-19 17:21:5611317 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11318 ClientSocketPool::SocketType::kHttp,
11319 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011320 false,
bncce36dca22015-04-21 22:11:2311321 },
[email protected]2d731a32010-04-29 01:04:0611322
bncce36dca22015-04-21 22:11:2311323 // SSL Tests
11324 {
Matt Menke4802de62019-03-08 22:47:5011325 "http_proxy",
11326 "https://www.example.org/http_connect_ssl",
Matt Menkef6edce752019-03-19 17:21:5611327 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11328 ClientSocketPool::SocketType::kSsl,
11329 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011330 true,
bncce36dca22015-04-21 22:11:2311331 },
[email protected]af3490e2010-10-16 21:02:2911332
bncce36dca22015-04-21 22:11:2311333 {
Matt Menke4802de62019-03-08 22:47:5011334 "http_proxy",
11335 "https://host.with.alternate/direct",
Matt Menkef6edce752019-03-19 17:21:5611336 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11337 ClientSocketPool::SocketType::kSsl,
11338 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011339 true,
bncce36dca22015-04-21 22:11:2311340 },
[email protected]45499252013-01-23 17:12:5611341
bncce36dca22015-04-21 22:11:2311342 {
Matt Menke4802de62019-03-08 22:47:5011343 "http_proxy",
11344 "ftp://ftp.google.com/http_proxy_normal",
Matt Menkef6edce752019-03-19 17:21:5611345 ClientSocketPool::GroupId(HostPortPair("ftp.google.com", 21),
11346 ClientSocketPool::SocketType::kFtp,
11347 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011348 false,
bncce36dca22015-04-21 22:11:2311349 },
[email protected]2d731a32010-04-29 01:04:0611350 };
11351
Avi Drissman4365a4782018-12-28 19:26:2411352 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911353 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911354 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11355 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911356 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611357 SetupSessionForGroupIdTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611358
mmenkee65e7af2015-10-13 17:16:4211359 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0611360
Matt Menkee8648fa2019-01-17 16:47:0711361 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11362 HostPortPair("http_proxy", 80));
Matt Menkef6edce752019-03-19 17:21:5611363 CaptureGroupIdTransportSocketPool* http_proxy_pool =
Matt Menked6fd2a52019-03-20 06:14:3611364 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911365 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011366 mock_pool_manager->SetSocketPool(proxy_server,
11367 base::WrapUnique(http_proxy_pool));
dchengc7eeda422015-12-26 03:56:4811368 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611369
11370 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611371 GroupIdTransactionHelper(tests[i].url, session.get()));
11372 EXPECT_EQ(tests[i].expected_group_id,
11373 http_proxy_pool->last_group_id_received());
[email protected]2d731a32010-04-29 01:04:0611374 }
[email protected]2d731a32010-04-29 01:04:0611375}
11376
Matt Menkef6edce752019-03-19 17:21:5611377TEST_F(HttpNetworkTransactionTest, GroupIdForSOCKSConnections) {
11378 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311379 {
Matt Menke4802de62019-03-08 22:47:5011380 "socks4://socks_proxy:1080",
11381 "http://www.example.org/socks4_direct",
Matt Menkef6edce752019-03-19 17:21:5611382 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11383 ClientSocketPool::SocketType::kHttp,
11384 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011385 false,
bncce36dca22015-04-21 22:11:2311386 },
11387 {
Matt Menke4802de62019-03-08 22:47:5011388 "socks5://socks_proxy:1080",
11389 "http://www.example.org/socks5_direct",
Matt Menkef6edce752019-03-19 17:21:5611390 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11391 ClientSocketPool::SocketType::kHttp,
11392 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011393 false,
bncce36dca22015-04-21 22:11:2311394 },
[email protected]2d731a32010-04-29 01:04:0611395
bncce36dca22015-04-21 22:11:2311396 // SSL Tests
11397 {
Matt Menke4802de62019-03-08 22:47:5011398 "socks4://socks_proxy:1080",
11399 "https://www.example.org/socks4_ssl",
Matt Menkef6edce752019-03-19 17:21:5611400 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11401 ClientSocketPool::SocketType::kSsl,
11402 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011403 true,
bncce36dca22015-04-21 22:11:2311404 },
11405 {
Matt Menke4802de62019-03-08 22:47:5011406 "socks5://socks_proxy:1080",
11407 "https://www.example.org/socks5_ssl",
Matt Menkef6edce752019-03-19 17:21:5611408 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11409 ClientSocketPool::SocketType::kSsl,
11410 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011411 true,
bncce36dca22015-04-21 22:11:2311412 },
[email protected]af3490e2010-10-16 21:02:2911413
bncce36dca22015-04-21 22:11:2311414 {
Matt Menke4802de62019-03-08 22:47:5011415 "socks4://socks_proxy:1080",
11416 "https://host.with.alternate/direct",
Matt Menkef6edce752019-03-19 17:21:5611417 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11418 ClientSocketPool::SocketType::kSsl,
11419 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011420 true,
bncce36dca22015-04-21 22:11:2311421 },
[email protected]04e5be32009-06-26 20:00:3111422 };
11423
Avi Drissman4365a4782018-12-28 19:26:2411424 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911425 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911426 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11427 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911428 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611429 SetupSessionForGroupIdTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0211430
mmenkee65e7af2015-10-13 17:16:4211431 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3111432
Matt Menkee8648fa2019-01-17 16:47:0711433 ProxyServer proxy_server(
11434 ProxyServer::FromURI(tests[i].proxy_server, ProxyServer::SCHEME_HTTP));
11435 ASSERT_TRUE(proxy_server.is_valid());
Matt Menkef6edce752019-03-19 17:21:5611436 CaptureGroupIdTransportSocketPool* socks_conn_pool =
Matt Menked6fd2a52019-03-20 06:14:3611437 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911438 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011439 mock_pool_manager->SetSocketPool(proxy_server,
11440 base::WrapUnique(socks_conn_pool));
dchengc7eeda422015-12-26 03:56:4811441 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3111442
bnc691fda62016-08-12 00:43:1611443 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3111444
[email protected]2d731a32010-04-29 01:04:0611445 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611446 GroupIdTransactionHelper(tests[i].url, session.get()));
11447 EXPECT_EQ(tests[i].expected_group_id,
11448 socks_conn_pool->last_group_id_received());
[email protected]04e5be32009-06-26 20:00:3111449 }
11450}
11451
bncd16676a2016-07-20 16:23:0111452TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2711453 HttpRequestInfo request;
11454 request.method = "GET";
bncce36dca22015-04-21 22:11:2311455 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011456 request.traffic_annotation =
11457 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711458
Ramin Halavatica8d5252018-03-12 05:33:4911459 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11460 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3211461
[email protected]69719062010-01-05 20:09:2111462 // This simulates failure resolving all hostnames; that means we will fail
11463 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0711464 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3211465
danakj1fd259a02016-04-16 03:17:0911466 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611467 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2511468
[email protected]49639fa2011-12-20 23:22:4111469 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2511470
tfarina42834112016-09-22 13:38:2011471 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111472 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2511473
[email protected]9172a982009-06-06 00:30:2511474 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111475 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2511476}
11477
Miriam Gershenson2a01b162018-03-22 22:54:4711478// LOAD_BYPASS_CACHE should trigger the host cache bypass.
11479TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
[email protected]cb9bf6ca2011-01-28 13:15:2711480 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1011481 HttpRequestInfo request_info;
11482 request_info.method = "GET";
Miriam Gershenson2a01b162018-03-22 22:54:4711483 request_info.load_flags = LOAD_BYPASS_CACHE;
maksim.sisov31452af2016-07-27 06:38:1011484 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011485 request_info.traffic_annotation =
11486 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711487
[email protected]a2c2fb92009-07-18 07:31:0411488 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1911489 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3211490
danakj1fd259a02016-04-16 03:17:0911491 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611492 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2811493
bncce36dca22015-04-21 22:11:2311494 // Warm up the host cache so it has an entry for "www.example.org".
Eric Orthf4db66a2019-02-19 21:35:3311495 int rv = session_deps_.host_resolver->LoadIntoCache(
11496 HostPortPair("www.example.org", 80), base::nullopt);
robpercival214763f2016-07-01 23:27:0111497 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2811498
bncce36dca22015-04-21 22:11:2311499 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2811500 // we can tell if the next lookup hit the cache, or the "network".
11501 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2311502 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2811503
11504 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
11505 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0611506 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
Ryan Sleevib8d7ea02018-05-07 20:01:0111507 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711508 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2811509
[email protected]3b9cca42009-06-16 01:08:2811510 // Run the request.
Eric Orthf4db66a2019-02-19 21:35:3311511 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2011512 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111513 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4111514 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2811515
11516 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2311517 // "www.example.org".
robpercival214763f2016-07-01 23:27:0111518 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2811519}
11520
[email protected]0877e3d2009-10-17 22:29:5711521// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0111522TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5711523 HttpRequestInfo request;
11524 request.method = "GET";
11525 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1011526 request.traffic_annotation =
11527 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711528
11529 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0611530 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711531 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111532 StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
[email protected]bb88e1d32013-05-03 23:11:0711533 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911534 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711535
[email protected]49639fa2011-12-20 23:22:4111536 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711537
bnc691fda62016-08-12 00:43:1611538 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711539
tfarina42834112016-09-22 13:38:2011540 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111541 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711542
11543 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111544 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5911545
11546 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611547 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911548 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711549}
11550
zmo9528c9f42015-08-04 22:12:0811551// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0111552TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5711553 HttpRequestInfo request;
11554 request.method = "GET";
11555 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1011556 request.traffic_annotation =
11557 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711558
11559 MockRead data_reads[] = {
11560 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0611561 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711562 };
11563
Ryan Sleevib8d7ea02018-05-07 20:01:0111564 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711565 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911566 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711567
[email protected]49639fa2011-12-20 23:22:4111568 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711569
bnc691fda62016-08-12 00:43:1611570 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711571
tfarina42834112016-09-22 13:38:2011572 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111573 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711574
11575 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111576 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811577
bnc691fda62016-08-12 00:43:1611578 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211579 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0811580
wezca1070932016-05-26 20:30:5211581 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0811582 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11583
11584 std::string response_data;
bnc691fda62016-08-12 00:43:1611585 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111586 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811587 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5911588
11589 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611590 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911591 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711592}
11593
11594// Make sure that a dropped connection while draining the body for auth
11595// restart does the right thing.
bncd16676a2016-07-20 16:23:0111596TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5711597 HttpRequestInfo request;
11598 request.method = "GET";
bncce36dca22015-04-21 22:11:2311599 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011600 request.traffic_annotation =
11601 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711602
11603 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311604 MockWrite(
11605 "GET / HTTP/1.1\r\n"
11606 "Host: www.example.org\r\n"
11607 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711608 };
11609
11610 MockRead data_reads1[] = {
11611 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
11612 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
11613 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11614 MockRead("Content-Length: 14\r\n\r\n"),
11615 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0611616 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711617 };
11618
Ryan Sleevib8d7ea02018-05-07 20:01:0111619 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0711620 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5711621
bnc691fda62016-08-12 00:43:1611622 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5711623 // be issuing -- the final header line contains the credentials.
11624 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311625 MockWrite(
11626 "GET / HTTP/1.1\r\n"
11627 "Host: www.example.org\r\n"
11628 "Connection: keep-alive\r\n"
11629 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711630 };
11631
11632 // Lastly, the server responds with the actual content.
11633 MockRead data_reads2[] = {
11634 MockRead("HTTP/1.1 200 OK\r\n"),
11635 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11636 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611637 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711638 };
11639
Ryan Sleevib8d7ea02018-05-07 20:01:0111640 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:0711641 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0911642 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711643
[email protected]49639fa2011-12-20 23:22:4111644 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5711645
bnc691fda62016-08-12 00:43:1611646 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011647
tfarina42834112016-09-22 13:38:2011648 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111649 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711650
11651 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111652 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711653
bnc691fda62016-08-12 00:43:1611654 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211655 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411656 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5711657
[email protected]49639fa2011-12-20 23:22:4111658 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5711659
bnc691fda62016-08-12 00:43:1611660 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0111661 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711662
11663 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111664 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711665
bnc691fda62016-08-12 00:43:1611666 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211667 ASSERT_TRUE(response);
11668 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5711669 EXPECT_EQ(100, response->headers->GetContentLength());
11670}
11671
11672// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0111673TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4911674 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11675 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711676
11677 HttpRequestInfo request;
11678 request.method = "GET";
bncce36dca22015-04-21 22:11:2311679 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011680 request.traffic_annotation =
11681 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711682
11683 MockRead proxy_reads[] = {
11684 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0611685 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5711686 };
11687
Ryan Sleevib8d7ea02018-05-07 20:01:0111688 StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
[email protected]8ddf8322012-02-23 18:08:0611689 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5711690
[email protected]bb88e1d32013-05-03 23:11:0711691 session_deps_.socket_factory->AddSocketDataProvider(&data);
11692 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5711693
[email protected]49639fa2011-12-20 23:22:4111694 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711695
[email protected]bb88e1d32013-05-03 23:11:0711696 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5711697
danakj1fd259a02016-04-16 03:17:0911698 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611699 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711700
tfarina42834112016-09-22 13:38:2011701 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111702 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711703
11704 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111705 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5711706}
11707
bncd16676a2016-07-20 16:23:0111708TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4611709 HttpRequestInfo request;
11710 request.method = "GET";
bncce36dca22015-04-21 22:11:2311711 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011712 request.traffic_annotation =
11713 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4611714
danakj1fd259a02016-04-16 03:17:0911715 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611716 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2711717
[email protected]e22e1362009-11-23 21:31:1211718 MockRead data_reads[] = {
11719 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611720 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1211721 };
[email protected]9492e4a2010-02-24 00:58:4611722
Ryan Sleevib8d7ea02018-05-07 20:01:0111723 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711724 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4611725
[email protected]49639fa2011-12-20 23:22:4111726 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4611727
tfarina42834112016-09-22 13:38:2011728 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111729 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4611730
robpercival214763f2016-07-01 23:27:0111731 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4611732
bnc691fda62016-08-12 00:43:1611733 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211734 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4611735
wezca1070932016-05-26 20:30:5211736 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4611737 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11738
11739 std::string response_data;
bnc691fda62016-08-12 00:43:1611740 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111741 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1211742}
11743
bncd16676a2016-07-20 16:23:0111744TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1511745 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5211746 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1411747 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2111748 UploadFileElementReader::ScopedOverridingContentLengthForTests
11749 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3311750
danakj1fd259a02016-04-16 03:17:0911751 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911752 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411753 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0711754 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211755 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711756
11757 HttpRequestInfo request;
11758 request.method = "POST";
bncce36dca22015-04-21 22:11:2311759 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711760 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011761 request.traffic_annotation =
11762 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711763
danakj1fd259a02016-04-16 03:17:0911764 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611765 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3311766
11767 MockRead data_reads[] = {
11768 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11769 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611770 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3311771 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111772 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711773 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3311774
[email protected]49639fa2011-12-20 23:22:4111775 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3311776
tfarina42834112016-09-22 13:38:2011777 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111778 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3311779
11780 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111781 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3311782
bnc691fda62016-08-12 00:43:1611783 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211784 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3311785
maksim.sisove869bf52016-06-23 17:11:5211786 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3311787
[email protected]dd3aa792013-07-16 19:10:2311788 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3311789}
11790
bncd16676a2016-07-20 16:23:0111791TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1511792 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5211793 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3611794 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4811795 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
11796 base::WriteFile(temp_file, temp_file_content.c_str(),
11797 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1111798 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3611799
danakj1fd259a02016-04-16 03:17:0911800 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911801 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411802 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0711803 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211804 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711805
11806 HttpRequestInfo request;
11807 request.method = "POST";
bncce36dca22015-04-21 22:11:2311808 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711809 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011810 request.traffic_annotation =
11811 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711812
[email protected]999dd8c2013-11-12 06:45:5411813 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0911814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611815 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3611816
Ryan Sleevib8d7ea02018-05-07 20:01:0111817 StaticSocketDataProvider data;
[email protected]bb88e1d32013-05-03 23:11:0711818 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3611819
[email protected]49639fa2011-12-20 23:22:4111820 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3611821
tfarina42834112016-09-22 13:38:2011822 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111823 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3611824
11825 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111826 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3611827
[email protected]dd3aa792013-07-16 19:10:2311828 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3611829}
11830
bncd16676a2016-07-20 16:23:0111831TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0311832 class FakeUploadElementReader : public UploadElementReader {
11833 public:
Chris Watkins7a41d3552017-12-01 02:13:2711834 FakeUploadElementReader() = default;
11835 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0311836
Matt Menkecc1d3a902018-02-05 18:27:3311837 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0311838
11839 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3311840 int Init(CompletionOnceCallback callback) override {
11841 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0311842 return ERR_IO_PENDING;
11843 }
avibf0746c2015-12-09 19:53:1411844 uint64_t GetContentLength() const override { return 0; }
11845 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2011846 int Read(IOBuffer* buf,
11847 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3311848 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0311849 return ERR_FAILED;
11850 }
11851
11852 private:
Matt Menkecc1d3a902018-02-05 18:27:3311853 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0311854 };
11855
11856 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0911857 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11858 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2211859 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0311860
11861 HttpRequestInfo request;
11862 request.method = "POST";
bncce36dca22015-04-21 22:11:2311863 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0311864 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1011865 request.traffic_annotation =
11866 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0311867
danakj1fd259a02016-04-16 03:17:0911868 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811869 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911870 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0311871
11872 StaticSocketDataProvider data;
11873 session_deps_.socket_factory->AddSocketDataProvider(&data);
11874
11875 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2011876 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111877 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5511878 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0311879
11880 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3311881 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
11882 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0311883
11884 // Return Init()'s result after the transaction gets destroyed.
11885 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3311886 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0311887}
11888
[email protected]aeefc9e82010-02-19 16:18:2711889// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0111890TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2711891 HttpRequestInfo request;
11892 request.method = "GET";
bncce36dca22015-04-21 22:11:2311893 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011894 request.traffic_annotation =
11895 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2711896
11897 // First transaction will request a resource and receive a Basic challenge
11898 // with realm="first_realm".
11899 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311900 MockWrite(
11901 "GET / HTTP/1.1\r\n"
11902 "Host: www.example.org\r\n"
11903 "Connection: keep-alive\r\n"
11904 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711905 };
11906 MockRead data_reads1[] = {
11907 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11908 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11909 "\r\n"),
11910 };
11911
bnc691fda62016-08-12 00:43:1611912 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2711913 // for first_realm. The server will reject and provide a challenge with
11914 // second_realm.
11915 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311916 MockWrite(
11917 "GET / HTTP/1.1\r\n"
11918 "Host: www.example.org\r\n"
11919 "Connection: keep-alive\r\n"
11920 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
11921 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711922 };
11923 MockRead data_reads2[] = {
11924 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11925 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
11926 "\r\n"),
11927 };
11928
11929 // This again fails, and goes back to first_realm. Make sure that the
11930 // entry is removed from cache.
11931 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2311932 MockWrite(
11933 "GET / HTTP/1.1\r\n"
11934 "Host: www.example.org\r\n"
11935 "Connection: keep-alive\r\n"
11936 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
11937 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711938 };
11939 MockRead data_reads3[] = {
11940 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11941 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11942 "\r\n"),
11943 };
11944
11945 // Try one last time (with the correct password) and get the resource.
11946 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2311947 MockWrite(
11948 "GET / HTTP/1.1\r\n"
11949 "Host: www.example.org\r\n"
11950 "Connection: keep-alive\r\n"
11951 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
11952 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711953 };
11954 MockRead data_reads4[] = {
11955 MockRead("HTTP/1.1 200 OK\r\n"
11956 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5011957 "Content-Length: 5\r\n"
11958 "\r\n"
11959 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2711960 };
11961
Ryan Sleevib8d7ea02018-05-07 20:01:0111962 StaticSocketDataProvider data1(data_reads1, data_writes1);
11963 StaticSocketDataProvider data2(data_reads2, data_writes2);
11964 StaticSocketDataProvider data3(data_reads3, data_writes3);
11965 StaticSocketDataProvider data4(data_reads4, data_writes4);
[email protected]bb88e1d32013-05-03 23:11:0711966 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11967 session_deps_.socket_factory->AddSocketDataProvider(&data2);
11968 session_deps_.socket_factory->AddSocketDataProvider(&data3);
11969 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2711970
[email protected]49639fa2011-12-20 23:22:4111971 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2711972
danakj1fd259a02016-04-16 03:17:0911973 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611974 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011975
[email protected]aeefc9e82010-02-19 16:18:2711976 // Issue the first request with Authorize headers. There should be a
11977 // password prompt for first_realm waiting to be filled in after the
11978 // transaction completes.
tfarina42834112016-09-22 13:38:2011979 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111980 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711981 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111982 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611983 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211984 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411985 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211986 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411987 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311988 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411989 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911990 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711991
11992 // Issue the second request with an incorrect password. There should be a
11993 // password prompt for second_realm waiting to be filled in after the
11994 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4111995 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1611996 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
11997 callback2.callback());
robpercival214763f2016-07-01 23:27:0111998 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711999 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0112000 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612001 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212002 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0412003 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5212004 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0412005 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4312006 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0412007 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1912008 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2712009
12010 // Issue the third request with another incorrect password. There should be
12011 // a password prompt for first_realm waiting to be filled in. If the password
12012 // prompt is not present, it indicates that the HttpAuthCacheEntry for
12013 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4112014 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1612015 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
12016 callback3.callback());
robpercival214763f2016-07-01 23:27:0112017 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2712018 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0112019 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612020 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212021 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0412022 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5212023 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0412024 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4312025 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0412026 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1912027 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2712028
12029 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4112030 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1612031 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
12032 callback4.callback());
robpercival214763f2016-07-01 23:27:0112033 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2712034 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0112035 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612036 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212037 ASSERT_TRUE(response);
12038 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2712039}
12040
Bence Béky230ac612017-08-30 19:17:0812041// Regression test for https://crbug.com/754395.
12042TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
12043 MockRead data_reads[] = {
12044 MockRead("HTTP/1.1 200 OK\r\n"),
12045 MockRead(kAlternativeServiceHttpHeader),
12046 MockRead("\r\n"),
12047 MockRead("hello world"),
12048 MockRead(SYNCHRONOUS, OK),
12049 };
12050
12051 HttpRequestInfo request;
12052 request.method = "GET";
12053 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012054 request.traffic_annotation =
12055 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0812056
Ryan Sleevib8d7ea02018-05-07 20:01:0112057 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:0812058 session_deps_.socket_factory->AddSocketDataProvider(&data);
12059
12060 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912061 ssl.ssl_info.cert =
12062 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12063 ASSERT_TRUE(ssl.ssl_info.cert);
12064 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0812065 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12066
12067 TestCompletionCallback callback;
12068
12069 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12070 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12071
12072 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12074
12075 url::SchemeHostPort test_server(request.url);
12076 HttpServerProperties* http_server_properties =
12077 session->http_server_properties();
12078 EXPECT_TRUE(
12079 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
12080
12081 EXPECT_THAT(callback.WaitForResult(), IsOk());
12082
12083 const HttpResponseInfo* response = trans.GetResponseInfo();
12084 ASSERT_TRUE(response);
12085 ASSERT_TRUE(response->headers);
12086 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12087 EXPECT_FALSE(response->was_fetched_via_spdy);
12088 EXPECT_FALSE(response->was_alpn_negotiated);
12089
12090 std::string response_data;
12091 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
12092 EXPECT_EQ("hello world", response_data);
12093
12094 EXPECT_TRUE(
12095 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
12096}
12097
bncd16676a2016-07-20 16:23:0112098TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5212099 MockRead data_reads[] = {
12100 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312101 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212102 MockRead("\r\n"),
12103 MockRead("hello world"),
12104 MockRead(SYNCHRONOUS, OK),
12105 };
12106
12107 HttpRequestInfo request;
12108 request.method = "GET";
bncb26024382016-06-29 02:39:4512109 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012110 request.traffic_annotation =
12111 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5212112
Ryan Sleevib8d7ea02018-05-07 20:01:0112113 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5212114 session_deps_.socket_factory->AddSocketDataProvider(&data);
12115
bncb26024382016-06-29 02:39:4512116 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912117 ssl.ssl_info.cert =
12118 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12119 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512120 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12121
bncc958faa2015-07-31 18:14:5212122 TestCompletionCallback callback;
12123
danakj1fd259a02016-04-16 03:17:0912124 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612125 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5212126
tfarina42834112016-09-22 13:38:2012127 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112128 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5212129
bncb26024382016-06-29 02:39:4512130 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4012131 HttpServerProperties* http_server_properties =
12132 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412133 EXPECT_TRUE(
12134 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5212135
robpercival214763f2016-07-01 23:27:0112136 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5212137
bnc691fda62016-08-12 00:43:1612138 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212139 ASSERT_TRUE(response);
12140 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5212141 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12142 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212143 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212144
12145 std::string response_data;
bnc691fda62016-08-12 00:43:1612146 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212147 EXPECT_EQ("hello world", response_data);
12148
zhongyic4de03032017-05-19 04:07:3412149 AlternativeServiceInfoVector alternative_service_info_vector =
12150 http_server_properties->GetAlternativeServiceInfos(test_server);
12151 ASSERT_EQ(1u, alternative_service_info_vector.size());
12152 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
12153 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412154 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5212155}
12156
bnce3dd56f2016-06-01 10:37:1112157// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0112158TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112159 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1112160 MockRead data_reads[] = {
12161 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312162 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1112163 MockRead("\r\n"),
12164 MockRead("hello world"),
12165 MockRead(SYNCHRONOUS, OK),
12166 };
12167
12168 HttpRequestInfo request;
12169 request.method = "GET";
12170 request.url = GURL("http://www.example.org/");
12171 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012172 request.traffic_annotation =
12173 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112174
Ryan Sleevib8d7ea02018-05-07 20:01:0112175 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112176 session_deps_.socket_factory->AddSocketDataProvider(&data);
12177
12178 TestCompletionCallback callback;
12179
12180 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612181 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112182
12183 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4012184 HttpServerProperties* http_server_properties =
12185 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412186 EXPECT_TRUE(
12187 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112188
tfarina42834112016-09-22 13:38:2012189 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112190 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12191 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1112192
bnc691fda62016-08-12 00:43:1612193 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1112194 ASSERT_TRUE(response);
12195 ASSERT_TRUE(response->headers);
12196 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12197 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212198 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1112199
12200 std::string response_data;
bnc691fda62016-08-12 00:43:1612201 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1112202 EXPECT_EQ("hello world", response_data);
12203
zhongyic4de03032017-05-19 04:07:3412204 EXPECT_TRUE(
12205 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112206}
12207
bnca86731e2017-04-17 12:31:2812208// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2512209// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0112210TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2512211 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2812212 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4512213
bnc8bef8da22016-05-30 01:28:2512214 HttpRequestInfo request;
12215 request.method = "GET";
bncb26024382016-06-29 02:39:4512216 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2512217 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012218 request.traffic_annotation =
12219 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2512220
12221 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12222 StaticSocketDataProvider first_data;
12223 first_data.set_connect_data(mock_connect);
12224 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512225 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612226 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512227 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2512228
12229 MockRead data_reads[] = {
12230 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12231 MockRead(ASYNC, OK),
12232 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112233 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnc8bef8da22016-05-30 01:28:2512234 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12235
12236 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12237
bnc525e175a2016-06-20 12:36:4012238 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2512239 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112240 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
12241 444);
bnc8bef8da22016-05-30 01:28:2512242 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112243 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2512244 url::SchemeHostPort(request.url), alternative_service, expiration);
12245
bnc691fda62016-08-12 00:43:1612246 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2512247 TestCompletionCallback callback;
12248
tfarina42834112016-09-22 13:38:2012249 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2512250 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112251 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2512252}
12253
bnce3dd56f2016-06-01 10:37:1112254// Regression test for https://crbug.com/615497:
12255// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0112256TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112257 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1112258 HttpRequestInfo request;
12259 request.method = "GET";
12260 request.url = GURL("http://www.example.org/");
12261 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012262 request.traffic_annotation =
12263 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112264
12265 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12266 StaticSocketDataProvider first_data;
12267 first_data.set_connect_data(mock_connect);
12268 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
12269
12270 MockRead data_reads[] = {
12271 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12272 MockRead(ASYNC, OK),
12273 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112274 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112275 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12276
12277 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12278
bnc525e175a2016-06-20 12:36:4012279 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1112280 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112281 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1112282 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112283 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1112284 url::SchemeHostPort(request.url), alternative_service, expiration);
12285
bnc691fda62016-08-12 00:43:1612286 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112287 TestCompletionCallback callback;
12288
tfarina42834112016-09-22 13:38:2012289 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1112290 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112291 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1112292}
12293
bncd16676a2016-07-20 16:23:0112294TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0812295 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0912296 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012297 HttpServerProperties* http_server_properties =
12298 session->http_server_properties();
bncb26024382016-06-29 02:39:4512299 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2112300 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0812301 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112302 http_server_properties->SetQuicAlternativeService(
12303 test_server, alternative_service, expiration,
12304 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3412305 EXPECT_EQ(
12306 1u,
12307 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0812308
12309 // Send a clear header.
12310 MockRead data_reads[] = {
12311 MockRead("HTTP/1.1 200 OK\r\n"),
12312 MockRead("Alt-Svc: clear\r\n"),
12313 MockRead("\r\n"),
12314 MockRead("hello world"),
12315 MockRead(SYNCHRONOUS, OK),
12316 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112317 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnc4f575852015-10-14 18:35:0812318 session_deps_.socket_factory->AddSocketDataProvider(&data);
12319
bncb26024382016-06-29 02:39:4512320 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912321 ssl.ssl_info.cert =
12322 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12323 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12325
bnc4f575852015-10-14 18:35:0812326 HttpRequestInfo request;
12327 request.method = "GET";
bncb26024382016-06-29 02:39:4512328 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012329 request.traffic_annotation =
12330 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0812331
12332 TestCompletionCallback callback;
12333
bnc691fda62016-08-12 00:43:1612334 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0812335
tfarina42834112016-09-22 13:38:2012336 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112337 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0812338
bnc691fda62016-08-12 00:43:1612339 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212340 ASSERT_TRUE(response);
12341 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0812342 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12343 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212344 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0812345
12346 std::string response_data;
bnc691fda62016-08-12 00:43:1612347 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0812348 EXPECT_EQ("hello world", response_data);
12349
zhongyic4de03032017-05-19 04:07:3412350 EXPECT_TRUE(
12351 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0812352}
12353
bncd16676a2016-07-20 16:23:0112354TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5212355 MockRead data_reads[] = {
12356 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312357 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
12358 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5212359 MockRead("hello world"),
12360 MockRead(SYNCHRONOUS, OK),
12361 };
12362
12363 HttpRequestInfo request;
12364 request.method = "GET";
bncb26024382016-06-29 02:39:4512365 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012366 request.traffic_annotation =
12367 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5212368
Ryan Sleevib8d7ea02018-05-07 20:01:0112369 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5212370 session_deps_.socket_factory->AddSocketDataProvider(&data);
12371
bncb26024382016-06-29 02:39:4512372 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912373 ssl.ssl_info.cert =
12374 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12375 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512376 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12377
bncc958faa2015-07-31 18:14:5212378 TestCompletionCallback callback;
12379
danakj1fd259a02016-04-16 03:17:0912380 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612381 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5212382
tfarina42834112016-09-22 13:38:2012383 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112384 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5212385
bncb26024382016-06-29 02:39:4512386 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4012387 HttpServerProperties* http_server_properties =
12388 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412389 EXPECT_TRUE(
12390 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5212391
robpercival214763f2016-07-01 23:27:0112392 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5212393
bnc691fda62016-08-12 00:43:1612394 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212395 ASSERT_TRUE(response);
12396 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5212397 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12398 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212399 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212400
12401 std::string response_data;
bnc691fda62016-08-12 00:43:1612402 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212403 EXPECT_EQ("hello world", response_data);
12404
zhongyic4de03032017-05-19 04:07:3412405 AlternativeServiceInfoVector alternative_service_info_vector =
12406 http_server_properties->GetAlternativeServiceInfos(test_server);
12407 ASSERT_EQ(2u, alternative_service_info_vector.size());
12408
12409 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
12410 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412411 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412412 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
12413 1234);
12414 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5412415 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5212416}
12417
bncd16676a2016-07-20 16:23:0112418TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612419 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212420 HostPortPair alternative("alternative.example.org", 443);
12421 std::string origin_url = "https://origin.example.org:443";
12422 std::string alternative_url = "https://alternative.example.org:443";
12423
12424 // Negotiate HTTP/1.1 with alternative.example.org.
12425 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612426 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212427 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12428
12429 // HTTP/1.1 data for request.
12430 MockWrite http_writes[] = {
12431 MockWrite("GET / HTTP/1.1\r\n"
12432 "Host: alternative.example.org\r\n"
12433 "Connection: keep-alive\r\n\r\n"),
12434 };
12435
12436 MockRead http_reads[] = {
12437 MockRead("HTTP/1.1 200 OK\r\n"
12438 "Content-Type: text/html; charset=iso-8859-1\r\n"
12439 "Content-Length: 40\r\n\r\n"
12440 "first HTTP/1.1 response from alternative"),
12441 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112442 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212443 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12444
12445 StaticSocketDataProvider data_refused;
12446 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12447 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12448
zhongyi3d4a55e72016-04-22 20:36:4612449 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0912450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012451 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212452 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112453 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0212454 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112455 http_server_properties->SetQuicAlternativeService(
12456 server, alternative_service, expiration,
12457 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0212458 // Mark the QUIC alternative service as broken.
12459 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
12460
zhongyi48704c182015-12-07 07:52:0212461 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612462 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212463 request.method = "GET";
12464 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1012465 request.traffic_annotation =
12466 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12467
zhongyi48704c182015-12-07 07:52:0212468 TestCompletionCallback callback;
12469 NetErrorDetails details;
12470 EXPECT_FALSE(details.quic_broken);
12471
tfarina42834112016-09-22 13:38:2012472 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612473 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212474 EXPECT_TRUE(details.quic_broken);
12475}
12476
bncd16676a2016-07-20 16:23:0112477TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612478 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212479 HostPortPair alternative1("alternative1.example.org", 443);
12480 HostPortPair alternative2("alternative2.example.org", 443);
12481 std::string origin_url = "https://origin.example.org:443";
12482 std::string alternative_url1 = "https://alternative1.example.org:443";
12483 std::string alternative_url2 = "https://alternative2.example.org:443";
12484
12485 // Negotiate HTTP/1.1 with alternative1.example.org.
12486 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612487 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212488 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12489
12490 // HTTP/1.1 data for request.
12491 MockWrite http_writes[] = {
12492 MockWrite("GET / HTTP/1.1\r\n"
12493 "Host: alternative1.example.org\r\n"
12494 "Connection: keep-alive\r\n\r\n"),
12495 };
12496
12497 MockRead http_reads[] = {
12498 MockRead("HTTP/1.1 200 OK\r\n"
12499 "Content-Type: text/html; charset=iso-8859-1\r\n"
12500 "Content-Length: 40\r\n\r\n"
12501 "first HTTP/1.1 response from alternative1"),
12502 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112503 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212504 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12505
12506 StaticSocketDataProvider data_refused;
12507 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12508 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12509
danakj1fd259a02016-04-16 03:17:0912510 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012511 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212512 session->http_server_properties();
12513
zhongyi3d4a55e72016-04-22 20:36:4612514 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0212515 AlternativeServiceInfoVector alternative_service_info_vector;
12516 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
12517
bnc3472afd2016-11-17 15:27:2112518 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2112519 alternative_service_info_vector.push_back(
12520 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12521 alternative_service1, expiration,
12522 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2112523 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2112524 alternative_service_info_vector.push_back(
12525 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12526 alternative_service2, expiration,
12527 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0212528
12529 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4612530 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0212531
12532 // Mark one of the QUIC alternative service as broken.
12533 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3412534 EXPECT_EQ(2u,
12535 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0212536
zhongyi48704c182015-12-07 07:52:0212537 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612538 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212539 request.method = "GET";
12540 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1012541 request.traffic_annotation =
12542 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12543
zhongyi48704c182015-12-07 07:52:0212544 TestCompletionCallback callback;
12545 NetErrorDetails details;
12546 EXPECT_FALSE(details.quic_broken);
12547
tfarina42834112016-09-22 13:38:2012548 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612549 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212550 EXPECT_FALSE(details.quic_broken);
12551}
12552
bncd16676a2016-07-20 16:23:0112553TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4212554 HttpRequestInfo request;
12555 request.method = "GET";
bncb26024382016-06-29 02:39:4512556 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012557 request.traffic_annotation =
12558 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4212559
[email protected]d973e99a2012-02-17 21:02:3612560 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4212561 StaticSocketDataProvider first_data;
12562 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712563 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512564 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612565 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512566 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4212567
12568 MockRead data_reads[] = {
12569 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12570 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612571 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4212572 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112573 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712574 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4212575
danakj1fd259a02016-04-16 03:17:0912576 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4212577
bnc525e175a2016-06-20 12:36:4012578 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312579 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4612580 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1112581 // Port must be < 1024, or the header will be ignored (since initial port was
12582 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2112583 // Port is ignored by MockConnect anyway.
12584 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12585 666);
bnc7dc7e1b42015-07-28 14:43:1212586 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112587 http_server_properties->SetHttp2AlternativeService(
12588 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4212589
bnc691fda62016-08-12 00:43:1612590 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112591 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4212592
tfarina42834112016-09-22 13:38:2012593 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112594 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12595 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4212596
bnc691fda62016-08-12 00:43:1612597 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212598 ASSERT_TRUE(response);
12599 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4212600 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12601
12602 std::string response_data;
bnc691fda62016-08-12 00:43:1612603 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4212604 EXPECT_EQ("hello world", response_data);
12605
zhongyic4de03032017-05-19 04:07:3412606 const AlternativeServiceInfoVector alternative_service_info_vector =
12607 http_server_properties->GetAlternativeServiceInfos(server);
12608 ASSERT_EQ(1u, alternative_service_info_vector.size());
12609 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412610 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412611 EXPECT_TRUE(
12612 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4212613}
12614
bnc55ff9da2015-08-19 18:42:3512615// Ensure that we are not allowed to redirect traffic via an alternate protocol
12616// to an unrestricted (port >= 1024) when the original traffic was on a
12617// restricted port (port < 1024). Ensure that we can redirect in all other
12618// cases.
bncd16676a2016-07-20 16:23:0112619TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1112620 HttpRequestInfo restricted_port_request;
12621 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512622 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112623 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012624 restricted_port_request.traffic_annotation =
12625 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112626
[email protected]d973e99a2012-02-17 21:02:3612627 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112628 StaticSocketDataProvider first_data;
12629 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712630 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112631
12632 MockRead data_reads[] = {
12633 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12634 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612635 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112636 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112637 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712638 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512639 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612640 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512641 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112642
danakj1fd259a02016-04-16 03:17:0912643 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112644
bnc525e175a2016-06-20 12:36:4012645 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312646 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112647 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112648 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12649 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212650 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112651 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612652 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012653 expiration);
[email protected]3912662a32011-10-04 00:51:1112654
bnc691fda62016-08-12 00:43:1612655 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112656 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112657
tfarina42834112016-09-22 13:38:2012658 int rv = trans.Start(&restricted_port_request, callback.callback(),
12659 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112660 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112661 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0112662 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1912663}
[email protected]3912662a32011-10-04 00:51:1112664
bnc55ff9da2015-08-19 18:42:3512665// Ensure that we are allowed to redirect traffic via an alternate protocol to
12666// an unrestricted (port >= 1024) when the original traffic was on a restricted
12667// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0112668TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0712669 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1912670
12671 HttpRequestInfo restricted_port_request;
12672 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512673 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1912674 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012675 restricted_port_request.traffic_annotation =
12676 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1912677
12678 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12679 StaticSocketDataProvider first_data;
12680 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712681 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1912682
12683 MockRead data_reads[] = {
12684 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12685 MockRead("hello world"),
12686 MockRead(ASYNC, OK),
12687 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112688 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712689 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512690 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612691 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512692 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1912693
danakj1fd259a02016-04-16 03:17:0912694 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1912695
bnc525e175a2016-06-20 12:36:4012696 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1912697 session->http_server_properties();
12698 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112699 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12700 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212701 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112702 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612703 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012704 expiration);
[email protected]c54c6962013-02-01 04:53:1912705
bnc691fda62016-08-12 00:43:1612706 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1912707 TestCompletionCallback callback;
12708
tfarina42834112016-09-22 13:38:2012709 EXPECT_EQ(ERR_IO_PENDING,
12710 trans.Start(&restricted_port_request, callback.callback(),
12711 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1912712 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0112713 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112714}
12715
bnc55ff9da2015-08-19 18:42:3512716// Ensure that we are not allowed to redirect traffic via an alternate protocol
12717// to an unrestricted (port >= 1024) when the original traffic was on a
12718// restricted port (port < 1024). Ensure that we can redirect in all other
12719// cases.
bncd16676a2016-07-20 16:23:0112720TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1112721 HttpRequestInfo restricted_port_request;
12722 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512723 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112724 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012725 restricted_port_request.traffic_annotation =
12726 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112727
[email protected]d973e99a2012-02-17 21:02:3612728 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112729 StaticSocketDataProvider first_data;
12730 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712731 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112732
12733 MockRead data_reads[] = {
12734 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12735 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612736 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112737 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112738 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712739 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112740
bncb26024382016-06-29 02:39:4512741 SSLSocketDataProvider ssl(ASYNC, OK);
12742 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12743
danakj1fd259a02016-04-16 03:17:0912744 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112745
bnc525e175a2016-06-20 12:36:4012746 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312747 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112748 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112749 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12750 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212751 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112752 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612753 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012754 expiration);
[email protected]3912662a32011-10-04 00:51:1112755
bnc691fda62016-08-12 00:43:1612756 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112757 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112758
tfarina42834112016-09-22 13:38:2012759 int rv = trans.Start(&restricted_port_request, callback.callback(),
12760 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112761 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112762 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112763 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112764}
12765
bnc55ff9da2015-08-19 18:42:3512766// Ensure that we are not allowed to redirect traffic via an alternate protocol
12767// to an unrestricted (port >= 1024) when the original traffic was on a
12768// restricted port (port < 1024). Ensure that we can redirect in all other
12769// cases.
bncd16676a2016-07-20 16:23:0112770TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1112771 HttpRequestInfo unrestricted_port_request;
12772 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512773 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112774 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012775 unrestricted_port_request.traffic_annotation =
12776 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112777
[email protected]d973e99a2012-02-17 21:02:3612778 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112779 StaticSocketDataProvider first_data;
12780 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712781 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112782
12783 MockRead data_reads[] = {
12784 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12785 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612786 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112787 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112788 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712789 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512790 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612791 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512792 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112793
danakj1fd259a02016-04-16 03:17:0912794 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112795
bnc525e175a2016-06-20 12:36:4012796 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312797 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112798 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112799 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12800 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212801 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112802 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612803 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012804 expiration);
[email protected]3912662a32011-10-04 00:51:1112805
bnc691fda62016-08-12 00:43:1612806 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112807 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112808
bnc691fda62016-08-12 00:43:1612809 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012810 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112811 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112812 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112813 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112814}
12815
bnc55ff9da2015-08-19 18:42:3512816// Ensure that we are not allowed to redirect traffic via an alternate protocol
12817// to an unrestricted (port >= 1024) when the original traffic was on a
12818// restricted port (port < 1024). Ensure that we can redirect in all other
12819// cases.
bncd16676a2016-07-20 16:23:0112820TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1112821 HttpRequestInfo unrestricted_port_request;
12822 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512823 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112824 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012825 unrestricted_port_request.traffic_annotation =
12826 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112827
[email protected]d973e99a2012-02-17 21:02:3612828 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112829 StaticSocketDataProvider first_data;
12830 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712831 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112832
12833 MockRead data_reads[] = {
12834 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12835 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612836 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112837 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112838 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712839 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112840
bncb26024382016-06-29 02:39:4512841 SSLSocketDataProvider ssl(ASYNC, OK);
12842 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12843
danakj1fd259a02016-04-16 03:17:0912844 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112845
bnc525e175a2016-06-20 12:36:4012846 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312847 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2212848 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2112849 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12850 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212851 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112852 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612853 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012854 expiration);
[email protected]3912662a32011-10-04 00:51:1112855
bnc691fda62016-08-12 00:43:1612856 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112857 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112858
bnc691fda62016-08-12 00:43:1612859 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012860 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112861 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112862 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0112863 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112864}
12865
bnc55ff9da2015-08-19 18:42:3512866// Ensure that we are not allowed to redirect traffic via an alternate protocol
Xida Chen9bfe0b62018-04-24 19:52:2112867// to an unsafe port, and that we resume the second HttpStreamFactory::Job once
12868// the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0112869TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0212870 HttpRequestInfo request;
12871 request.method = "GET";
bncce36dca22015-04-21 22:11:2312872 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012873 request.traffic_annotation =
12874 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0212875
12876 // The alternate protocol request will error out before we attempt to connect,
12877 // so only the standard HTTP request will try to connect.
12878 MockRead data_reads[] = {
12879 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12880 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612881 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0212882 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112883 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712884 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0212885
danakj1fd259a02016-04-16 03:17:0912886 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0212887
bnc525e175a2016-06-20 12:36:4012888 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0212889 session->http_server_properties();
12890 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2112891 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12892 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1212893 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112894 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612895 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0212896
bnc691fda62016-08-12 00:43:1612897 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0212898 TestCompletionCallback callback;
12899
tfarina42834112016-09-22 13:38:2012900 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112901 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0212902 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0112903 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212904
bnc691fda62016-08-12 00:43:1612905 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212906 ASSERT_TRUE(response);
12907 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0212908 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12909
12910 std::string response_data;
bnc691fda62016-08-12 00:43:1612911 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212912 EXPECT_EQ("hello world", response_data);
12913}
12914
bncd16676a2016-07-20 16:23:0112915TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5412916 HttpRequestInfo request;
12917 request.method = "GET";
bncb26024382016-06-29 02:39:4512918 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012919 request.traffic_annotation =
12920 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412921
12922 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212923 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312924 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212925 MockRead("\r\n"),
12926 MockRead("hello world"),
12927 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12928 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5412929
Ryan Sleevib8d7ea02018-05-07 20:01:0112930 StaticSocketDataProvider first_transaction(data_reads,
12931 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712932 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512933 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612934 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512935 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412936
bnc032658ba2016-09-26 18:17:1512937 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412938
Ryan Hamilton0239aac2018-05-19 00:03:1312939 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512940 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112941 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412942
Raul Tambre94493c652019-03-11 17:18:3512943 spdy::SpdySerializedFrame resp(
12944 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1312945 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412946 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112947 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412948 };
12949
Ryan Sleevib8d7ea02018-05-07 20:01:0112950 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712951 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412952
[email protected]d973e99a2012-02-17 21:02:3612953 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112954 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512955 hanging_non_alternate_protocol_socket.set_connect_data(
12956 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712957 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512958 &hanging_non_alternate_protocol_socket);
12959
[email protected]49639fa2011-12-20 23:22:4112960 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412961
danakj1fd259a02016-04-16 03:17:0912962 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812963 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912964 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412965
tfarina42834112016-09-22 13:38:2012966 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112967 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12968 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412969
12970 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212971 ASSERT_TRUE(response);
12972 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412973 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12974
12975 std::string response_data;
robpercival214763f2016-07-01 23:27:0112976 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412977 EXPECT_EQ("hello world", response_data);
12978
bnc87dcefc2017-05-25 12:47:5812979 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912980 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412981
tfarina42834112016-09-22 13:38:2012982 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12984 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412985
12986 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212987 ASSERT_TRUE(response);
12988 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212989 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312990 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212991 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412992
robpercival214763f2016-07-01 23:27:0112993 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412994 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5412995}
12996
bncd16676a2016-07-20 16:23:0112997TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5512998 HttpRequestInfo request;
12999 request.method = "GET";
bncb26024382016-06-29 02:39:4513000 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013001 request.traffic_annotation =
13002 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5513003
bncb26024382016-06-29 02:39:4513004 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5513005 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213006 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313007 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213008 MockRead("\r\n"),
13009 MockRead("hello world"),
13010 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13011 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5513012 };
13013
Ryan Sleevib8d7ea02018-05-07 20:01:0113014 StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
bncb26024382016-06-29 02:39:4513015 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5513016
bncb26024382016-06-29 02:39:4513017 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4913018 ssl_http11.ssl_info.cert =
13019 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
13020 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4513021 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
13022
13023 // Second transaction starts an alternative and a non-alternative Job.
13024 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3613025 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113026 StaticSocketDataProvider hanging_socket1;
mmenkecc2298e2015-12-07 18:20:1813027 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1813028 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
13029
Ryan Sleevib8d7ea02018-05-07 20:01:0113030 StaticSocketDataProvider hanging_socket2;
mmenkecc2298e2015-12-07 18:20:1813031 hanging_socket2.set_connect_data(never_finishing_connect);
13032 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5513033
bncb26024382016-06-29 02:39:4513034 // Third transaction starts an alternative and a non-alternative job.
13035 // The non-alternative job hangs, but the alternative one succeeds.
13036 // The second transaction, still pending, binds to this socket.
Ryan Hamilton0239aac2018-05-19 00:03:1313037 spdy::SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4513038 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1313039 spdy::SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4513040 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5513041 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113042 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5513043 };
Raul Tambre94493c652019-03-11 17:18:3513044 spdy::SpdySerializedFrame resp1(
13045 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1313046 spdy::SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
Raul Tambre94493c652019-03-11 17:18:3513047 spdy::SpdySerializedFrame resp2(
13048 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1313049 spdy::SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5513050 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113051 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
13052 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1313053 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5513054 };
13055
Ryan Sleevib8d7ea02018-05-07 20:01:0113056 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713057 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5513058
bnc032658ba2016-09-26 18:17:1513059 AddSSLSocketData();
bncb26024382016-06-29 02:39:4513060
Ryan Sleevib8d7ea02018-05-07 20:01:0113061 StaticSocketDataProvider hanging_socket3;
mmenkecc2298e2015-12-07 18:20:1813062 hanging_socket3.set_connect_data(never_finishing_connect);
13063 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5513064
danakj1fd259a02016-04-16 03:17:0913065 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4113066 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5013067 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5513068
tfarina42834112016-09-22 13:38:2013069 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113070 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13071 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513072
13073 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213074 ASSERT_TRUE(response);
13075 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513076 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13077
13078 std::string response_data;
robpercival214763f2016-07-01 23:27:0113079 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513080 EXPECT_EQ("hello world", response_data);
13081
[email protected]49639fa2011-12-20 23:22:4113082 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5013083 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2013084 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5513086
[email protected]49639fa2011-12-20 23:22:4113087 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5013088 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2013089 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5513091
robpercival214763f2016-07-01 23:27:0113092 EXPECT_THAT(callback2.WaitForResult(), IsOk());
13093 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513094
13095 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213096 ASSERT_TRUE(response);
13097 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213098 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5513099 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213100 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113101 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513102 EXPECT_EQ("hello!", response_data);
13103
13104 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5213105 ASSERT_TRUE(response);
13106 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213107 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5513108 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213109 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113110 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513111 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5513112}
13113
bncd16676a2016-07-20 16:23:0113114TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
Bence Békybcae37092018-06-12 04:18:5313115 session_deps_.host_resolver->set_synchronous_mode(true);
13116
[email protected]2d6728692011-03-12 01:39:5513117 HttpRequestInfo request;
13118 request.method = "GET";
bncb26024382016-06-29 02:39:4513119 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013120 request.traffic_annotation =
13121 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5513122
13123 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213124 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313125 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213126 MockRead("\r\n"),
13127 MockRead("hello world"),
13128 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13129 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5513130 };
13131
Ryan Sleevib8d7ea02018-05-07 20:01:0113132 StaticSocketDataProvider first_transaction(data_reads,
13133 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713134 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5513135
[email protected]8ddf8322012-02-23 18:08:0613136 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4913137 ssl.ssl_info.cert =
13138 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
13139 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0713140 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5513141
[email protected]d973e99a2012-02-17 21:02:3613142 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113143 StaticSocketDataProvider hanging_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513144 hanging_alternate_protocol_socket.set_connect_data(
13145 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713146 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513147 &hanging_alternate_protocol_socket);
13148
bncb26024382016-06-29 02:39:4513149 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
Ryan Sleevib8d7ea02018-05-07 20:01:0113150 StaticSocketDataProvider second_transaction(data_reads,
13151 base::span<MockWrite>());
mmenkecc2298e2015-12-07 18:20:1813152 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4513153 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5513154
[email protected]49639fa2011-12-20 23:22:4113155 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5513156
danakj1fd259a02016-04-16 03:17:0913157 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813158 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913159 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5513160
tfarina42834112016-09-22 13:38:2013161 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113162 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13163 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513164
13165 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213166 ASSERT_TRUE(response);
13167 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513168 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13169
13170 std::string response_data;
robpercival214763f2016-07-01 23:27:0113171 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513172 EXPECT_EQ("hello world", response_data);
13173
bnc87dcefc2017-05-25 12:47:5813174 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913175 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5513176
tfarina42834112016-09-22 13:38:2013177 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113178 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13179 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513180
13181 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213182 ASSERT_TRUE(response);
13183 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513184 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13185 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213186 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5513187
robpercival214763f2016-07-01 23:27:0113188 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513189 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5513190}
13191
bnc2e884782016-08-11 19:45:1913192// Test that proxy is resolved using the origin url,
13193// regardless of the alternative server.
13194TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
13195 // Configure proxy to bypass www.example.org, which is the origin URL.
13196 ProxyConfig proxy_config;
13197 proxy_config.proxy_rules().ParseFromString("myproxy:70");
13198 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4913199 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
13200 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1913201
13202 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1913203 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1913204 &capturing_proxy_resolver);
13205
13206 TestNetLog net_log;
13207
Bence Béky53a5aef2018-03-29 21:54:1213208 session_deps_.proxy_resolution_service =
13209 std::make_unique<ProxyResolutionService>(
13210 std::move(proxy_config_service), std::move(proxy_resolver_factory),
13211 &net_log);
bnc2e884782016-08-11 19:45:1913212
13213 session_deps_.net_log = &net_log;
13214
13215 // Configure alternative service with a hostname that is not bypassed by the
13216 // proxy.
13217 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13218 HttpServerProperties* http_server_properties =
13219 session->http_server_properties();
13220 url::SchemeHostPort server("https", "www.example.org", 443);
13221 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2113222 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1913223 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2113224 http_server_properties->SetHttp2AlternativeService(
13225 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1913226
13227 // Non-alternative job should hang.
13228 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113229 StaticSocketDataProvider hanging_alternate_protocol_socket;
bnc2e884782016-08-11 19:45:1913230 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
13231 session_deps_.socket_factory->AddSocketDataProvider(
13232 &hanging_alternate_protocol_socket);
13233
bnc032658ba2016-09-26 18:17:1513234 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1913235
13236 HttpRequestInfo request;
13237 request.method = "GET";
13238 request.url = GURL("https://www.example.org/");
13239 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1013240 request.traffic_annotation =
13241 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1913242
Ryan Hamilton0239aac2018-05-19 00:03:1313243 spdy::SpdySerializedFrame req(
bnc2e884782016-08-11 19:45:1913244 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
13245
13246 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
13247
Ryan Hamilton0239aac2018-05-19 00:03:1313248 spdy::SpdySerializedFrame resp(
13249 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13250 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc2e884782016-08-11 19:45:1913251 MockRead spdy_reads[] = {
13252 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
13253 };
13254
Ryan Sleevib8d7ea02018-05-07 20:01:0113255 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
bnc2e884782016-08-11 19:45:1913256 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
13257
13258 TestCompletionCallback callback;
13259
13260 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13261
tfarina42834112016-09-22 13:38:2013262 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1913263 EXPECT_THAT(callback.GetResult(rv), IsOk());
13264
13265 const HttpResponseInfo* response = trans.GetResponseInfo();
13266 ASSERT_TRUE(response);
13267 ASSERT_TRUE(response->headers);
13268 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13269 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213270 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1913271
13272 std::string response_data;
13273 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13274 EXPECT_EQ("hello!", response_data);
13275
13276 // Origin host bypasses proxy, no resolution should have happened.
13277 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
13278}
13279
bncd16676a2016-07-20 16:23:0113280TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1113281 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4213282 proxy_config.set_auto_detect(true);
13283 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1113284
sammc5dd160c2015-04-02 02:43:1313285 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4913286 session_deps_.proxy_resolution_service =
13287 std::make_unique<ProxyResolutionService>(
13288 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
13289 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
13290 std::make_unique<CapturingProxyResolverFactory>(
13291 &capturing_proxy_resolver),
13292 nullptr);
vishal.b62985ca92015-04-17 08:45:5113293 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0713294 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1113295
13296 HttpRequestInfo request;
13297 request.method = "GET";
bncb26024382016-06-29 02:39:4513298 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013299 request.traffic_annotation =
13300 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1113301
13302 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213303 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313304 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213305 MockRead("\r\n"),
13306 MockRead("hello world"),
13307 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13308 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1113309 };
13310
Ryan Sleevib8d7ea02018-05-07 20:01:0113311 StaticSocketDataProvider first_transaction(data_reads,
13312 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713313 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513314 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613315 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513316 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1113317
bnc032658ba2016-09-26 18:17:1513318 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1113319
Ryan Hamilton0239aac2018-05-19 00:03:1313320 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513321 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1113322 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313323 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2513324 "CONNECT www.example.org:443 HTTP/1.1\r\n"
13325 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1313326 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4113327 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1113328 };
13329
[email protected]d911f1b2010-05-05 22:39:4213330 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
13331
Raul Tambre94493c652019-03-11 17:18:3513332 spdy::SpdySerializedFrame resp(
13333 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1313334 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1113335 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113336 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
13337 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1113338 };
13339
Ryan Sleevib8d7ea02018-05-07 20:01:0113340 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713341 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1113342
[email protected]d973e99a2012-02-17 21:02:3613343 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113344 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513345 hanging_non_alternate_protocol_socket.set_connect_data(
13346 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713347 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513348 &hanging_non_alternate_protocol_socket);
13349
[email protected]49639fa2011-12-20 23:22:4113350 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1113351
danakj1fd259a02016-04-16 03:17:0913352 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813353 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913354 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113355
tfarina42834112016-09-22 13:38:2013356 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4113357 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13358 EXPECT_THAT(callback.WaitForResult(), IsOk());
13359
13360 const HttpResponseInfo* response = trans->GetResponseInfo();
13361 ASSERT_TRUE(response);
13362 ASSERT_TRUE(response->headers);
13363 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
13364 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213365 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4113366
13367 std::string response_data;
13368 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
13369 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1113370
bnc87dcefc2017-05-25 12:47:5813371 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913372 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113373
tfarina42834112016-09-22 13:38:2013374 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113375 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13376 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1113377
mmenkea2dcd3bf2016-08-16 21:49:4113378 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213379 ASSERT_TRUE(response);
13380 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213381 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313382 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213383 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1113384
robpercival214763f2016-07-01 23:27:0113385 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1113386 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4513387 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
13388 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313389 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2313390 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313391 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1113392
[email protected]029c83b62013-01-24 05:28:2013393 LoadTimingInfo load_timing_info;
13394 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
13395 TestLoadTimingNotReusedWithPac(load_timing_info,
13396 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1113397}
[email protected]631f1322010-04-30 17:59:1113398
bncd16676a2016-07-20 16:23:0113399TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4813400 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5413401 HttpRequestInfo request;
13402 request.method = "GET";
bncb26024382016-06-29 02:39:4513403 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013404 request.traffic_annotation =
13405 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5413406
13407 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213408 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313409 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213410 MockRead("\r\n"),
13411 MockRead("hello world"),
13412 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5413413 };
13414
Ryan Sleevib8d7ea02018-05-07 20:01:0113415 StaticSocketDataProvider first_transaction(data_reads,
13416 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713417 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513418 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613419 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513420 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5413421
bnc032658ba2016-09-26 18:17:1513422 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5413423
Ryan Hamilton0239aac2018-05-19 00:03:1313424 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513425 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113426 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5413427
Raul Tambre94493c652019-03-11 17:18:3513428 spdy::SpdySerializedFrame resp(
13429 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1313430 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5413431 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113432 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5413433 };
13434
Ryan Sleevib8d7ea02018-05-07 20:01:0113435 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713436 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5413437
[email protected]83039bb2011-12-09 18:43:5513438 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5413439
danakj1fd259a02016-04-16 03:17:0913440 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5413441
bnc87dcefc2017-05-25 12:47:5813442 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913443 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413444
tfarina42834112016-09-22 13:38:2013445 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113446 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13447 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413448
13449 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213450 ASSERT_TRUE(response);
13451 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5413452 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13453
13454 std::string response_data;
robpercival214763f2016-07-01 23:27:0113455 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413456 EXPECT_EQ("hello world", response_data);
13457
13458 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2513459 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013460 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1113461 PRIVACY_MODE_DISABLED,
13462 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2713463 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213464 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3813465
bnc87dcefc2017-05-25 12:47:5813466 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913467 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413468
tfarina42834112016-09-22 13:38:2013469 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13471 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413472
13473 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213474 ASSERT_TRUE(response);
13475 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213476 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313477 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213478 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5413479
robpercival214763f2016-07-01 23:27:0113480 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413481 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4213482}
13483
[email protected]044de0642010-06-17 10:42:1513484// GenerateAuthToken is a mighty big test.
13485// It tests all permutation of GenerateAuthToken behavior:
13486// - Synchronous and Asynchronous completion.
13487// - OK or error on completion.
13488// - Direct connection, non-authenticating proxy, and authenticating proxy.
13489// - HTTP or HTTPS backend (to include proxy tunneling).
13490// - Non-authenticating and authenticating backend.
13491//
[email protected]fe3b7dc2012-02-03 19:52:0913492// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1513493// problems generating an auth token for an authenticating proxy, we don't
13494// need to test all permutations of the backend server).
13495//
13496// The test proceeds by going over each of the configuration cases, and
13497// potentially running up to three rounds in each of the tests. The TestConfig
13498// specifies both the configuration for the test as well as the expectations
13499// for the results.
bncd16676a2016-07-20 16:23:0113500TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5013501 static const char kServer[] = "http://www.example.com";
13502 static const char kSecureServer[] = "https://www.example.com";
13503 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1513504
13505 enum AuthTiming {
13506 AUTH_NONE,
13507 AUTH_SYNC,
13508 AUTH_ASYNC,
13509 };
13510
13511 const MockWrite kGet(
13512 "GET / HTTP/1.1\r\n"
13513 "Host: www.example.com\r\n"
13514 "Connection: keep-alive\r\n\r\n");
13515 const MockWrite kGetProxy(
13516 "GET http://www.example.com/ HTTP/1.1\r\n"
13517 "Host: www.example.com\r\n"
13518 "Proxy-Connection: keep-alive\r\n\r\n");
13519 const MockWrite kGetAuth(
13520 "GET / HTTP/1.1\r\n"
13521 "Host: www.example.com\r\n"
13522 "Connection: keep-alive\r\n"
13523 "Authorization: auth_token\r\n\r\n");
13524 const MockWrite kGetProxyAuth(
13525 "GET http://www.example.com/ HTTP/1.1\r\n"
13526 "Host: www.example.com\r\n"
13527 "Proxy-Connection: keep-alive\r\n"
13528 "Proxy-Authorization: auth_token\r\n\r\n");
13529 const MockWrite kGetAuthThroughProxy(
13530 "GET http://www.example.com/ HTTP/1.1\r\n"
13531 "Host: www.example.com\r\n"
13532 "Proxy-Connection: keep-alive\r\n"
13533 "Authorization: auth_token\r\n\r\n");
13534 const MockWrite kGetAuthWithProxyAuth(
13535 "GET http://www.example.com/ HTTP/1.1\r\n"
13536 "Host: www.example.com\r\n"
13537 "Proxy-Connection: keep-alive\r\n"
13538 "Proxy-Authorization: auth_token\r\n"
13539 "Authorization: auth_token\r\n\r\n");
13540 const MockWrite kConnect(
13541 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713542 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513543 "Proxy-Connection: keep-alive\r\n\r\n");
13544 const MockWrite kConnectProxyAuth(
13545 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713546 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513547 "Proxy-Connection: keep-alive\r\n"
13548 "Proxy-Authorization: auth_token\r\n\r\n");
13549
13550 const MockRead kSuccess(
13551 "HTTP/1.1 200 OK\r\n"
13552 "Content-Type: text/html; charset=iso-8859-1\r\n"
13553 "Content-Length: 3\r\n\r\n"
13554 "Yes");
13555 const MockRead kFailure(
13556 "Should not be called.");
13557 const MockRead kServerChallenge(
13558 "HTTP/1.1 401 Unauthorized\r\n"
13559 "WWW-Authenticate: Mock realm=server\r\n"
13560 "Content-Type: text/html; charset=iso-8859-1\r\n"
13561 "Content-Length: 14\r\n\r\n"
13562 "Unauthorized\r\n");
13563 const MockRead kProxyChallenge(
13564 "HTTP/1.1 407 Unauthorized\r\n"
13565 "Proxy-Authenticate: Mock realm=proxy\r\n"
13566 "Proxy-Connection: close\r\n"
13567 "Content-Type: text/html; charset=iso-8859-1\r\n"
13568 "Content-Length: 14\r\n\r\n"
13569 "Unauthorized\r\n");
13570 const MockRead kProxyConnected(
13571 "HTTP/1.1 200 Connection Established\r\n\r\n");
13572
13573 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
13574 // no constructors, but the C++ compiler on Windows warns about
13575 // unspecified data in compound literals. So, moved to using constructors,
13576 // and TestRound's created with the default constructor should not be used.
13577 struct TestRound {
13578 TestRound()
Raul Tambre94493c652019-03-11 17:18:3513579 : expected_rv(ERR_UNEXPECTED),
13580 extra_write(nullptr),
13581 extra_read(nullptr) {}
Raul Tambre8335a6d2019-02-21 16:57:4313582 TestRound(const MockWrite& write_arg,
13583 const MockRead& read_arg,
[email protected]044de0642010-06-17 10:42:1513584 int expected_rv_arg)
13585 : write(write_arg),
13586 read(read_arg),
13587 expected_rv(expected_rv_arg),
Raul Tambre94493c652019-03-11 17:18:3513588 extra_write(nullptr),
13589 extra_read(nullptr) {}
[email protected]044de0642010-06-17 10:42:1513590 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
13591 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0113592 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1513593 : write(write_arg),
13594 read(read_arg),
13595 expected_rv(expected_rv_arg),
13596 extra_write(extra_write_arg),
13597 extra_read(extra_read_arg) {
13598 }
13599 MockWrite write;
13600 MockRead read;
13601 int expected_rv;
13602 const MockWrite* extra_write;
13603 const MockRead* extra_read;
13604 };
13605
13606 static const int kNoSSL = 500;
13607
13608 struct TestConfig {
asanka463ca4262016-11-16 02:34:3113609 int line_number;
thestig9d3bb0c2015-01-24 00:49:5113610 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1513611 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3113612 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5113613 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1513614 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3113615 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1513616 int num_auth_rounds;
13617 int first_ssl_round;
asankae2257db2016-10-11 22:03:1613618 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1513619 } test_configs[] = {
asankac93076192016-10-03 15:46:0213620 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113621 {__LINE__,
13622 nullptr,
asankac93076192016-10-03 15:46:0213623 AUTH_NONE,
13624 OK,
13625 kServer,
13626 AUTH_NONE,
13627 OK,
13628 1,
13629 kNoSSL,
13630 {TestRound(kGet, kSuccess, OK)}},
13631 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113632 {__LINE__,
13633 nullptr,
asankac93076192016-10-03 15:46:0213634 AUTH_NONE,
13635 OK,
13636 kServer,
13637 AUTH_SYNC,
13638 OK,
13639 2,
13640 kNoSSL,
13641 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513642 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113643 {__LINE__,
13644 nullptr,
asankac93076192016-10-03 15:46:0213645 AUTH_NONE,
13646 OK,
13647 kServer,
13648 AUTH_SYNC,
13649 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613650 3,
13651 kNoSSL,
13652 {TestRound(kGet, kServerChallenge, OK),
13653 TestRound(kGet, kServerChallenge, OK),
13654 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113655 {__LINE__,
13656 nullptr,
asankae2257db2016-10-11 22:03:1613657 AUTH_NONE,
13658 OK,
13659 kServer,
13660 AUTH_SYNC,
13661 ERR_UNSUPPORTED_AUTH_SCHEME,
13662 2,
13663 kNoSSL,
13664 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113665 {__LINE__,
13666 nullptr,
asankae2257db2016-10-11 22:03:1613667 AUTH_NONE,
13668 OK,
13669 kServer,
13670 AUTH_SYNC,
13671 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
13672 2,
13673 kNoSSL,
13674 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113675 {__LINE__,
13676 kProxy,
asankae2257db2016-10-11 22:03:1613677 AUTH_SYNC,
13678 ERR_FAILED,
13679 kServer,
13680 AUTH_NONE,
13681 OK,
13682 2,
13683 kNoSSL,
13684 {TestRound(kGetProxy, kProxyChallenge, OK),
13685 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113686 {__LINE__,
13687 kProxy,
asankae2257db2016-10-11 22:03:1613688 AUTH_ASYNC,
13689 ERR_FAILED,
13690 kServer,
13691 AUTH_NONE,
13692 OK,
13693 2,
13694 kNoSSL,
13695 {TestRound(kGetProxy, kProxyChallenge, OK),
13696 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113697 {__LINE__,
13698 nullptr,
asankae2257db2016-10-11 22:03:1613699 AUTH_NONE,
13700 OK,
13701 kServer,
13702 AUTH_SYNC,
13703 ERR_FAILED,
asankac93076192016-10-03 15:46:0213704 2,
13705 kNoSSL,
13706 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613707 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113708 {__LINE__,
13709 nullptr,
asankae2257db2016-10-11 22:03:1613710 AUTH_NONE,
13711 OK,
13712 kServer,
13713 AUTH_ASYNC,
13714 ERR_FAILED,
13715 2,
13716 kNoSSL,
13717 {TestRound(kGet, kServerChallenge, OK),
13718 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113719 {__LINE__,
13720 nullptr,
asankac93076192016-10-03 15:46:0213721 AUTH_NONE,
13722 OK,
13723 kServer,
13724 AUTH_ASYNC,
13725 OK,
13726 2,
13727 kNoSSL,
13728 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513729 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113730 {__LINE__,
13731 nullptr,
asankac93076192016-10-03 15:46:0213732 AUTH_NONE,
13733 OK,
13734 kServer,
13735 AUTH_ASYNC,
13736 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613737 3,
asankac93076192016-10-03 15:46:0213738 kNoSSL,
13739 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613740 // The second round uses a HttpAuthHandlerMock that always succeeds.
13741 TestRound(kGet, kServerChallenge, OK),
13742 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213743 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113744 {__LINE__,
13745 kProxy,
asankac93076192016-10-03 15:46:0213746 AUTH_NONE,
13747 OK,
13748 kServer,
13749 AUTH_NONE,
13750 OK,
13751 1,
13752 kNoSSL,
13753 {TestRound(kGetProxy, kSuccess, OK)}},
13754 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113755 {__LINE__,
13756 kProxy,
asankac93076192016-10-03 15:46:0213757 AUTH_NONE,
13758 OK,
13759 kServer,
13760 AUTH_SYNC,
13761 OK,
13762 2,
13763 kNoSSL,
13764 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513765 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113766 {__LINE__,
13767 kProxy,
asankac93076192016-10-03 15:46:0213768 AUTH_NONE,
13769 OK,
13770 kServer,
13771 AUTH_SYNC,
13772 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613773 3,
asankac93076192016-10-03 15:46:0213774 kNoSSL,
13775 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613776 TestRound(kGetProxy, kServerChallenge, OK),
13777 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113778 {__LINE__,
13779 kProxy,
asankac93076192016-10-03 15:46:0213780 AUTH_NONE,
13781 OK,
13782 kServer,
13783 AUTH_ASYNC,
13784 OK,
13785 2,
13786 kNoSSL,
13787 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513788 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113789 {__LINE__,
13790 kProxy,
asankac93076192016-10-03 15:46:0213791 AUTH_NONE,
13792 OK,
13793 kServer,
13794 AUTH_ASYNC,
13795 ERR_INVALID_AUTH_CREDENTIALS,
13796 2,
13797 kNoSSL,
13798 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613799 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213800 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113801 {__LINE__,
13802 kProxy,
asankac93076192016-10-03 15:46:0213803 AUTH_SYNC,
13804 OK,
13805 kServer,
13806 AUTH_NONE,
13807 OK,
13808 2,
13809 kNoSSL,
13810 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513811 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113812 {__LINE__,
13813 kProxy,
asankac93076192016-10-03 15:46:0213814 AUTH_SYNC,
13815 ERR_INVALID_AUTH_CREDENTIALS,
13816 kServer,
13817 AUTH_NONE,
13818 OK,
13819 2,
13820 kNoSSL,
13821 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613822 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113823 {__LINE__,
13824 kProxy,
asankac93076192016-10-03 15:46:0213825 AUTH_ASYNC,
13826 OK,
13827 kServer,
13828 AUTH_NONE,
13829 OK,
13830 2,
13831 kNoSSL,
13832 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513833 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113834 {__LINE__,
13835 kProxy,
asankac93076192016-10-03 15:46:0213836 AUTH_ASYNC,
13837 ERR_INVALID_AUTH_CREDENTIALS,
13838 kServer,
13839 AUTH_NONE,
13840 OK,
13841 2,
13842 kNoSSL,
13843 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613844 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113845 {__LINE__,
13846 kProxy,
13847 AUTH_ASYNC,
13848 ERR_INVALID_AUTH_CREDENTIALS,
13849 kServer,
13850 AUTH_NONE,
13851 OK,
13852 3,
13853 kNoSSL,
13854 {TestRound(kGetProxy, kProxyChallenge, OK),
13855 TestRound(kGetProxy, kProxyChallenge, OK),
13856 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213857 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113858 {__LINE__,
13859 kProxy,
asankac93076192016-10-03 15:46:0213860 AUTH_SYNC,
13861 OK,
13862 kServer,
13863 AUTH_SYNC,
13864 OK,
13865 3,
13866 kNoSSL,
13867 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513868 TestRound(kGetProxyAuth, kServerChallenge, OK),
13869 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113870 {__LINE__,
13871 kProxy,
asankac93076192016-10-03 15:46:0213872 AUTH_SYNC,
13873 OK,
13874 kServer,
13875 AUTH_SYNC,
13876 ERR_INVALID_AUTH_CREDENTIALS,
13877 3,
13878 kNoSSL,
13879 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513880 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613881 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113882 {__LINE__,
13883 kProxy,
asankac93076192016-10-03 15:46:0213884 AUTH_ASYNC,
13885 OK,
13886 kServer,
13887 AUTH_SYNC,
13888 OK,
13889 3,
13890 kNoSSL,
13891 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513892 TestRound(kGetProxyAuth, kServerChallenge, OK),
13893 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113894 {__LINE__,
13895 kProxy,
asankac93076192016-10-03 15:46:0213896 AUTH_ASYNC,
13897 OK,
13898 kServer,
13899 AUTH_SYNC,
13900 ERR_INVALID_AUTH_CREDENTIALS,
13901 3,
13902 kNoSSL,
13903 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513904 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613905 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113906 {__LINE__,
13907 kProxy,
asankac93076192016-10-03 15:46:0213908 AUTH_SYNC,
13909 OK,
13910 kServer,
13911 AUTH_ASYNC,
13912 OK,
13913 3,
13914 kNoSSL,
13915 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513916 TestRound(kGetProxyAuth, kServerChallenge, OK),
13917 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113918 {__LINE__,
13919 kProxy,
13920 AUTH_SYNC,
13921 ERR_INVALID_AUTH_CREDENTIALS,
13922 kServer,
13923 AUTH_ASYNC,
13924 OK,
13925 4,
13926 kNoSSL,
13927 {TestRound(kGetProxy, kProxyChallenge, OK),
13928 TestRound(kGetProxy, kProxyChallenge, OK),
13929 TestRound(kGetProxyAuth, kServerChallenge, OK),
13930 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
13931 {__LINE__,
13932 kProxy,
asankac93076192016-10-03 15:46:0213933 AUTH_SYNC,
13934 OK,
13935 kServer,
13936 AUTH_ASYNC,
13937 ERR_INVALID_AUTH_CREDENTIALS,
13938 3,
13939 kNoSSL,
13940 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513941 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613942 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113943 {__LINE__,
13944 kProxy,
asankac93076192016-10-03 15:46:0213945 AUTH_ASYNC,
13946 OK,
13947 kServer,
13948 AUTH_ASYNC,
13949 OK,
13950 3,
13951 kNoSSL,
13952 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513953 TestRound(kGetProxyAuth, kServerChallenge, OK),
13954 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113955 {__LINE__,
13956 kProxy,
asankac93076192016-10-03 15:46:0213957 AUTH_ASYNC,
13958 OK,
13959 kServer,
13960 AUTH_ASYNC,
13961 ERR_INVALID_AUTH_CREDENTIALS,
13962 3,
13963 kNoSSL,
13964 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513965 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613966 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113967 {__LINE__,
13968 kProxy,
13969 AUTH_ASYNC,
13970 ERR_INVALID_AUTH_CREDENTIALS,
13971 kServer,
13972 AUTH_ASYNC,
13973 ERR_INVALID_AUTH_CREDENTIALS,
13974 4,
13975 kNoSSL,
13976 {TestRound(kGetProxy, kProxyChallenge, OK),
13977 TestRound(kGetProxy, kProxyChallenge, OK),
13978 TestRound(kGetProxyAuth, kServerChallenge, OK),
13979 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213980 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113981 {__LINE__,
13982 nullptr,
asankac93076192016-10-03 15:46:0213983 AUTH_NONE,
13984 OK,
13985 kSecureServer,
13986 AUTH_NONE,
13987 OK,
13988 1,
13989 0,
13990 {TestRound(kGet, kSuccess, OK)}},
13991 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113992 {__LINE__,
13993 nullptr,
asankac93076192016-10-03 15:46:0213994 AUTH_NONE,
13995 OK,
13996 kSecureServer,
13997 AUTH_SYNC,
13998 OK,
13999 2,
14000 0,
14001 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1514002 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114003 {__LINE__,
14004 nullptr,
asankac93076192016-10-03 15:46:0214005 AUTH_NONE,
14006 OK,
14007 kSecureServer,
14008 AUTH_SYNC,
14009 ERR_INVALID_AUTH_CREDENTIALS,
14010 2,
14011 0,
asankae2257db2016-10-11 22:03:1614012 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114013 {__LINE__,
14014 nullptr,
asankac93076192016-10-03 15:46:0214015 AUTH_NONE,
14016 OK,
14017 kSecureServer,
14018 AUTH_ASYNC,
14019 OK,
14020 2,
14021 0,
14022 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1514023 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114024 {__LINE__,
14025 nullptr,
asankac93076192016-10-03 15:46:0214026 AUTH_NONE,
14027 OK,
14028 kSecureServer,
14029 AUTH_ASYNC,
14030 ERR_INVALID_AUTH_CREDENTIALS,
14031 2,
14032 0,
asankae2257db2016-10-11 22:03:1614033 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0214034 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3114035 {__LINE__,
14036 kProxy,
asankac93076192016-10-03 15:46:0214037 AUTH_NONE,
14038 OK,
14039 kSecureServer,
14040 AUTH_NONE,
14041 OK,
14042 1,
14043 0,
14044 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
14045 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3114046 {__LINE__,
14047 kProxy,
asankac93076192016-10-03 15:46:0214048 AUTH_NONE,
14049 OK,
14050 kSecureServer,
14051 AUTH_SYNC,
14052 OK,
14053 2,
14054 0,
14055 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514056 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114057 {__LINE__,
14058 kProxy,
asankac93076192016-10-03 15:46:0214059 AUTH_NONE,
14060 OK,
14061 kSecureServer,
14062 AUTH_SYNC,
14063 ERR_INVALID_AUTH_CREDENTIALS,
14064 2,
14065 0,
14066 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1614067 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114068 {__LINE__,
14069 kProxy,
asankac93076192016-10-03 15:46:0214070 AUTH_NONE,
14071 OK,
14072 kSecureServer,
14073 AUTH_ASYNC,
14074 OK,
14075 2,
14076 0,
14077 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514078 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114079 {__LINE__,
14080 kProxy,
asankac93076192016-10-03 15:46:0214081 AUTH_NONE,
14082 OK,
14083 kSecureServer,
14084 AUTH_ASYNC,
14085 ERR_INVALID_AUTH_CREDENTIALS,
14086 2,
14087 0,
14088 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1614089 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0214090 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3114091 {__LINE__,
14092 kProxy,
asankac93076192016-10-03 15:46:0214093 AUTH_SYNC,
14094 OK,
14095 kSecureServer,
14096 AUTH_NONE,
14097 OK,
14098 2,
14099 1,
14100 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1514101 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114102 {__LINE__,
14103 kProxy,
asankac93076192016-10-03 15:46:0214104 AUTH_SYNC,
14105 ERR_INVALID_AUTH_CREDENTIALS,
14106 kSecureServer,
14107 AUTH_NONE,
14108 OK,
14109 2,
14110 kNoSSL,
14111 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1614112 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114113 {__LINE__,
14114 kProxy,
asankae2257db2016-10-11 22:03:1614115 AUTH_SYNC,
14116 ERR_UNSUPPORTED_AUTH_SCHEME,
14117 kSecureServer,
14118 AUTH_NONE,
14119 OK,
14120 2,
14121 kNoSSL,
14122 {TestRound(kConnect, kProxyChallenge, OK),
14123 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114124 {__LINE__,
14125 kProxy,
asankae2257db2016-10-11 22:03:1614126 AUTH_SYNC,
14127 ERR_UNEXPECTED,
14128 kSecureServer,
14129 AUTH_NONE,
14130 OK,
14131 2,
14132 kNoSSL,
14133 {TestRound(kConnect, kProxyChallenge, OK),
14134 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3114135 {__LINE__,
14136 kProxy,
asankac93076192016-10-03 15:46:0214137 AUTH_ASYNC,
14138 OK,
14139 kSecureServer,
14140 AUTH_NONE,
14141 OK,
14142 2,
14143 1,
14144 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1514145 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114146 {__LINE__,
14147 kProxy,
asankac93076192016-10-03 15:46:0214148 AUTH_ASYNC,
14149 ERR_INVALID_AUTH_CREDENTIALS,
14150 kSecureServer,
14151 AUTH_NONE,
14152 OK,
14153 2,
14154 kNoSSL,
14155 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1614156 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0214157 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3114158 {__LINE__,
14159 kProxy,
asankac93076192016-10-03 15:46:0214160 AUTH_SYNC,
14161 OK,
14162 kSecureServer,
14163 AUTH_SYNC,
14164 OK,
14165 3,
14166 1,
14167 {TestRound(kConnect, kProxyChallenge, OK),
14168 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14169 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514170 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114171 {__LINE__,
14172 kProxy,
asankac93076192016-10-03 15:46:0214173 AUTH_SYNC,
14174 OK,
14175 kSecureServer,
14176 AUTH_SYNC,
14177 ERR_INVALID_AUTH_CREDENTIALS,
14178 3,
14179 1,
14180 {TestRound(kConnect, kProxyChallenge, OK),
14181 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14182 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614183 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114184 {__LINE__,
14185 kProxy,
asankac93076192016-10-03 15:46:0214186 AUTH_ASYNC,
14187 OK,
14188 kSecureServer,
14189 AUTH_SYNC,
14190 OK,
14191 3,
14192 1,
14193 {TestRound(kConnect, kProxyChallenge, OK),
14194 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14195 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514196 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114197 {__LINE__,
14198 kProxy,
asankac93076192016-10-03 15:46:0214199 AUTH_ASYNC,
14200 OK,
14201 kSecureServer,
14202 AUTH_SYNC,
14203 ERR_INVALID_AUTH_CREDENTIALS,
14204 3,
14205 1,
14206 {TestRound(kConnect, kProxyChallenge, OK),
14207 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14208 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614209 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114210 {__LINE__,
14211 kProxy,
asankac93076192016-10-03 15:46:0214212 AUTH_SYNC,
14213 OK,
14214 kSecureServer,
14215 AUTH_ASYNC,
14216 OK,
14217 3,
14218 1,
14219 {TestRound(kConnect, kProxyChallenge, OK),
14220 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14221 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514222 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114223 {__LINE__,
14224 kProxy,
asankac93076192016-10-03 15:46:0214225 AUTH_SYNC,
14226 OK,
14227 kSecureServer,
14228 AUTH_ASYNC,
14229 ERR_INVALID_AUTH_CREDENTIALS,
14230 3,
14231 1,
14232 {TestRound(kConnect, kProxyChallenge, OK),
14233 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14234 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614235 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114236 {__LINE__,
14237 kProxy,
asankac93076192016-10-03 15:46:0214238 AUTH_ASYNC,
14239 OK,
14240 kSecureServer,
14241 AUTH_ASYNC,
14242 OK,
14243 3,
14244 1,
14245 {TestRound(kConnect, kProxyChallenge, OK),
14246 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14247 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514248 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114249 {__LINE__,
14250 kProxy,
asankac93076192016-10-03 15:46:0214251 AUTH_ASYNC,
14252 OK,
14253 kSecureServer,
14254 AUTH_ASYNC,
14255 ERR_INVALID_AUTH_CREDENTIALS,
14256 3,
14257 1,
14258 {TestRound(kConnect, kProxyChallenge, OK),
14259 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14260 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614261 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114262 {__LINE__,
14263 kProxy,
14264 AUTH_ASYNC,
14265 ERR_INVALID_AUTH_CREDENTIALS,
14266 kSecureServer,
14267 AUTH_ASYNC,
14268 ERR_INVALID_AUTH_CREDENTIALS,
14269 4,
14270 2,
14271 {TestRound(kConnect, kProxyChallenge, OK),
14272 TestRound(kConnect, kProxyChallenge, OK),
14273 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14274 &kServerChallenge),
14275 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1514276 };
14277
asanka463ca4262016-11-16 02:34:3114278 for (const auto& test_config : test_configs) {
14279 SCOPED_TRACE(::testing::Message() << "Test config at "
14280 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0814281 HttpAuthHandlerMock::Factory* auth_factory(
14282 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714283 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4914284 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2614285
14286 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1514287 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3114288 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0814289 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14290 std::string auth_challenge = "Mock realm=proxy";
14291 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2414292 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14293 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0814294 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2014295 empty_ssl_info, origin,
14296 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814297 auth_handler->SetGenerateExpectation(
14298 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114299 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0814300 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
14301 }
[email protected]044de0642010-06-17 10:42:1514302 }
14303 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0014304 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1514305 std::string auth_challenge = "Mock realm=server";
14306 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2414307 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14308 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1514309 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014310 empty_ssl_info, origin,
14311 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514312 auth_handler->SetGenerateExpectation(
14313 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114314 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0814315 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1614316
14317 // The second handler always succeeds. It should only be used where there
14318 // are multiple auth sessions for server auth in the same network
14319 // transaction using the same auth scheme.
14320 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1914321 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1614322 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
14323 empty_ssl_info, origin,
14324 NetLogWithSource());
14325 second_handler->SetGenerateExpectation(true, OK);
14326 auth_factory->AddMockHandler(second_handler.release(),
14327 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1514328 }
14329 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5914330 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914331 ProxyResolutionService::CreateFixed(test_config.proxy_url,
14332 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514333 } else {
Bence Béky53a5aef2018-03-29 21:54:1214334 session_deps_.proxy_resolution_service =
14335 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1514336 }
14337
14338 HttpRequestInfo request;
14339 request.method = "GET";
14340 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e2018-02-07 07:41:1014341 request.traffic_annotation =
14342 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514343
danakj1fd259a02016-04-16 03:17:0914344 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1514345
rchcb68dc62015-05-21 04:45:3614346 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
14347
14348 std::vector<std::vector<MockRead>> mock_reads(1);
14349 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1514350 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214351 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1514352 const TestRound& read_write_round = test_config.rounds[round];
14353
14354 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3614355 mock_reads.back().push_back(read_write_round.read);
14356 mock_writes.back().push_back(read_write_round.write);
14357
14358 // kProxyChallenge uses Proxy-Connection: close which means that the
14359 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5414360 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3614361 mock_reads.push_back(std::vector<MockRead>());
14362 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1514363 }
14364
rchcb68dc62015-05-21 04:45:3614365 if (read_write_round.extra_read) {
14366 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1514367 }
rchcb68dc62015-05-21 04:45:3614368 if (read_write_round.extra_write) {
14369 mock_writes.back().push_back(*read_write_round.extra_write);
14370 }
[email protected]044de0642010-06-17 10:42:1514371
14372 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1514373 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0714374 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1514375 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3614376 }
[email protected]044de0642010-06-17 10:42:1514377
danakj1fd259a02016-04-16 03:17:0914378 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3614379 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1914380 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:0114381 mock_reads[i], mock_writes[i]));
rchcb68dc62015-05-21 04:45:3614382 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3214383 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3614384 }
14385
mmenkecc2298e2015-12-07 18:20:1814386 // Transaction must be created after DataProviders, so it's destroyed before
14387 // they are as well.
14388 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14389
rchcb68dc62015-05-21 04:45:3614390 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214391 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3614392 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1514393 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4114394 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1514395 int rv;
14396 if (round == 0) {
tfarina42834112016-09-22 13:38:2014397 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514398 } else {
[email protected]49639fa2011-12-20 23:22:4114399 rv = trans.RestartWithAuth(
14400 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1514401 }
14402 if (rv == ERR_IO_PENDING)
14403 rv = callback.WaitForResult();
14404
14405 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1614406 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5014407 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5514408 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1514409 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
14410 continue;
14411 }
14412 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5214413 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1514414 } else {
wezca1070932016-05-26 20:30:5214415 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1614416 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1514417 }
14418 }
[email protected]e5ae96a2010-04-14 20:12:4514419 }
14420}
14421
bncd16676a2016-07-20 16:23:0114422TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1414423 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1414424 HttpAuthHandlerMock::Factory* auth_factory(
14425 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714426 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1214427 session_deps_.proxy_resolution_service =
14428 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0714429 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
[email protected]c871bce92010-07-15 21:51:1414430
14431 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14432 auth_handler->set_connection_based(true);
14433 std::string auth_challenge = "Mock realm=server";
14434 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2414435 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14436 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4914437 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1414438 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014439 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814440 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1414441
[email protected]c871bce92010-07-15 21:51:1414442 int rv = OK;
Raul Tambre94493c652019-03-11 17:18:3514443 const HttpResponseInfo* response = nullptr;
[email protected]c871bce92010-07-15 21:51:1414444 HttpRequestInfo request;
14445 request.method = "GET";
14446 request.url = origin;
Ramin Halavatib5e433e2018-02-07 07:41:1014447 request.traffic_annotation =
14448 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714449
danakj1fd259a02016-04-16 03:17:0914450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1014451
14452 // Use a TCP Socket Pool with only one connection per group. This is used
14453 // to validate that the TCP socket is not released to the pool between
14454 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4214455 HttpNetworkSessionPeer session_peer(session.get());
Matt Menked6fd2a52019-03-20 06:14:3614456 CommonConnectJobParams common_connect_job_params(
14457 session->CreateCommonConnectJobParams());
[email protected]ab739042011-04-07 15:22:2814458 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
Tarun Bansala7635092019-02-20 10:00:5914459 50, // Max sockets for pool
14460 1, // Max sockets per group
14461 base::TimeDelta::FromSeconds(10), // unused_idle_socket_timeout
Matt Menked6fd2a52019-03-20 06:14:3614462 &common_connect_job_params, session_deps_.ssl_config_service.get());
Jeremy Roman0579ed62017-08-29 15:56:1914463 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4014464 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
14465 base::WrapUnique(transport_pool));
dchengc7eeda422015-12-26 03:56:4814466 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1014467
bnc691fda62016-08-12 00:43:1614468 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114469 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1414470
14471 const MockWrite kGet(
14472 "GET / HTTP/1.1\r\n"
14473 "Host: www.example.com\r\n"
14474 "Connection: keep-alive\r\n\r\n");
14475 const MockWrite kGetAuth(
14476 "GET / HTTP/1.1\r\n"
14477 "Host: www.example.com\r\n"
14478 "Connection: keep-alive\r\n"
14479 "Authorization: auth_token\r\n\r\n");
14480
14481 const MockRead kServerChallenge(
14482 "HTTP/1.1 401 Unauthorized\r\n"
14483 "WWW-Authenticate: Mock realm=server\r\n"
14484 "Content-Type: text/html; charset=iso-8859-1\r\n"
14485 "Content-Length: 14\r\n\r\n"
14486 "Unauthorized\r\n");
14487 const MockRead kSuccess(
14488 "HTTP/1.1 200 OK\r\n"
14489 "Content-Type: text/html; charset=iso-8859-1\r\n"
14490 "Content-Length: 3\r\n\r\n"
14491 "Yes");
14492
14493 MockWrite writes[] = {
14494 // First round
14495 kGet,
14496 // Second round
14497 kGetAuth,
14498 // Third round
14499 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3014500 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1014501 kGetAuth,
14502 // Competing request
14503 kGet,
[email protected]c871bce92010-07-15 21:51:1414504 };
14505 MockRead reads[] = {
14506 // First round
14507 kServerChallenge,
14508 // Second round
14509 kServerChallenge,
14510 // Third round
[email protected]eca50e122010-09-11 14:03:3014511 kServerChallenge,
14512 // Fourth round
[email protected]c871bce92010-07-15 21:51:1414513 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1014514 // Competing response
14515 kSuccess,
[email protected]c871bce92010-07-15 21:51:1414516 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114517 StaticSocketDataProvider data_provider(reads, writes);
[email protected]bb88e1d32013-05-03 23:11:0714518 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1414519
Matt Menkef6edce752019-03-19 17:21:5614520 const ClientSocketPool::GroupId kSocketGroup(
14521 HostPortPair("www.example.com", 80), ClientSocketPool::SocketType::kHttp,
14522 false /* privacy_mode */);
[email protected]7ef4cbbb2011-02-06 11:19:1014523
14524 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1414525 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2014526 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1414527 if (rv == ERR_IO_PENDING)
14528 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114529 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614530 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214531 ASSERT_TRUE(response);
14532 EXPECT_TRUE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314533 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114534 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14535 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414536
[email protected]7ef4cbbb2011-02-06 11:19:1014537 // In between rounds, another request comes in for the same domain.
14538 // It should not be able to grab the TCP socket that trans has already
14539 // claimed.
bnc691fda62016-08-12 00:43:1614540 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114541 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2014542 rv = trans_compete.Start(&request, callback_compete.callback(),
14543 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114544 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1014545 // callback_compete.WaitForResult at this point would stall forever,
14546 // since the HttpNetworkTransaction does not release the request back to
14547 // the pool until after authentication completes.
14548
14549 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1414550 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614551 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414552 if (rv == ERR_IO_PENDING)
14553 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114554 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614555 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214556 ASSERT_TRUE(response);
14557 EXPECT_FALSE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314558 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114559 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14560 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414561
[email protected]7ef4cbbb2011-02-06 11:19:1014562 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1414563 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614564 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414565 if (rv == ERR_IO_PENDING)
14566 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114567 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614568 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214569 ASSERT_TRUE(response);
14570 EXPECT_FALSE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314571 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114572 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14573 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3014574
[email protected]7ef4cbbb2011-02-06 11:19:1014575 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3014576 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614577 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3014578 if (rv == ERR_IO_PENDING)
14579 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114580 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614581 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214582 ASSERT_TRUE(response);
14583 EXPECT_FALSE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314584 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014585
asanka463ca4262016-11-16 02:34:3114586 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
14587 // auth handler should transition to a DONE state in concert with the remote
14588 // server. But that's not something we can test here with a mock handler.
14589 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
14590 auth_handler->state());
14591
[email protected]7ef4cbbb2011-02-06 11:19:1014592 // Read the body since the fourth round was successful. This will also
14593 // release the socket back to the pool.
Victor Costan9c7302b2018-08-27 16:39:4414594 scoped_refptr<IOBufferWithSize> io_buf =
14595 base::MakeRefCounted<IOBufferWithSize>(50);
bnc691fda62016-08-12 00:43:1614596 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014597 if (rv == ERR_IO_PENDING)
14598 rv = callback.WaitForResult();
14599 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614600 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014601 EXPECT_EQ(0, rv);
14602 // There are still 0 idle sockets, since the trans_compete transaction
14603 // will be handed it immediately after trans releases it to the group.
Raul Tambre8335a6d2019-02-21 16:57:4314604 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014605
14606 // The competing request can now finish. Wait for the headers and then
14607 // read the body.
14608 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0114609 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614610 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014611 if (rv == ERR_IO_PENDING)
14612 rv = callback.WaitForResult();
14613 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614614 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014615 EXPECT_EQ(0, rv);
14616
14617 // Finally, the socket is released to the group.
Raul Tambre8335a6d2019-02-21 16:57:4314618 EXPECT_EQ(1u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1414619}
14620
[email protected]65041fa2010-05-21 06:56:5314621// This tests the case that a request is issued via http instead of spdy after
14622// npn is negotiated.
bncd16676a2016-07-20 16:23:0114623TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5314624 HttpRequestInfo request;
14625 request.method = "GET";
bncce36dca22015-04-21 22:11:2314626 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014627 request.traffic_annotation =
14628 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5314629
14630 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314631 MockWrite(
14632 "GET / HTTP/1.1\r\n"
14633 "Host: www.example.org\r\n"
14634 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5314635 };
14636
14637 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5214638 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4314639 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5214640 MockRead("\r\n"),
14641 MockRead("hello world"),
14642 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5314643 };
14644
[email protected]8ddf8322012-02-23 18:08:0614645 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614646 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5314647
[email protected]bb88e1d32013-05-03 23:11:0714648 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5314649
Ryan Sleevib8d7ea02018-05-07 20:01:0114650 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714651 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5314652
[email protected]49639fa2011-12-20 23:22:4114653 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5314654
danakj1fd259a02016-04-16 03:17:0914655 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614656 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5314657
tfarina42834112016-09-22 13:38:2014658 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5314659
robpercival214763f2016-07-01 23:27:0114660 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14661 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5314662
bnc691fda62016-08-12 00:43:1614663 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214664 ASSERT_TRUE(response);
14665 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5314666 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14667
14668 std::string response_data;
bnc691fda62016-08-12 00:43:1614669 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5314670 EXPECT_EQ("hello world", response_data);
14671
14672 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214673 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5314674}
[email protected]26ef6582010-06-24 02:30:4714675
bnc55ff9da2015-08-19 18:42:3514676// Simulate the SSL handshake completing with an NPN negotiation followed by an
14677// immediate server closing of the socket.
14678// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0114679TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4714680 HttpRequestInfo request;
14681 request.method = "GET";
bncce36dca22015-04-21 22:11:2314682 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014683 request.traffic_annotation =
14684 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4714685
[email protected]8ddf8322012-02-23 18:08:0614686 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614687 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714688 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4714689
Ryan Hamilton0239aac2018-05-19 00:03:1314690 spdy::SpdySerializedFrame req(
14691 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114692 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4714693
14694 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614695 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4714696 };
14697
Ryan Sleevib8d7ea02018-05-07 20:01:0114698 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714699 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4714700
[email protected]49639fa2011-12-20 23:22:4114701 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4714702
danakj1fd259a02016-04-16 03:17:0914703 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614704 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4714705
tfarina42834112016-09-22 13:38:2014706 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114707 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14708 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4714709}
[email protected]65d34382010-07-01 18:12:2614710
[email protected]795cbf82013-07-22 09:37:2714711// A subclass of HttpAuthHandlerMock that records the request URL when
14712// it gets it. This is needed since the auth handler may get destroyed
14713// before we get a chance to query it.
14714class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
14715 public:
14716 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
14717
Chris Watkins7a41d3552017-12-01 02:13:2714718 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2714719
14720 protected:
dchengb03027d2014-10-21 12:00:2014721 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
14722 const HttpRequestInfo* request,
Bence Béky7236fb72018-08-01 14:35:0914723 CompletionOnceCallback callback,
dchengb03027d2014-10-21 12:00:2014724 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2714725 *url_ = request->url;
14726 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
Bence Béky7236fb72018-08-01 14:35:0914727 credentials, request, std::move(callback), auth_token);
[email protected]795cbf82013-07-22 09:37:2714728 }
14729
14730 private:
14731 GURL* url_;
14732};
14733
[email protected]8e6441ca2010-08-19 05:56:3814734// Test that if we cancel the transaction as the connection is completing, that
14735// everything tears down correctly.
bncd16676a2016-07-20 16:23:0114736TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3814737 // Setup everything about the connection to complete synchronously, so that
14738 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
14739 // for is the callback from the HttpStreamRequest.
14740 // Then cancel the transaction.
14741 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3614742 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3814743 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614744 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
14745 MockRead(SYNCHRONOUS, "hello world"),
14746 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3814747 };
14748
[email protected]8e6441ca2010-08-19 05:56:3814749 HttpRequestInfo request;
14750 request.method = "GET";
bncce36dca22015-04-21 22:11:2314751 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014752 request.traffic_annotation =
14753 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3814754
danakj1fd259a02016-04-16 03:17:0914755 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5814756 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1914757 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2714758
Ryan Sleevib8d7ea02018-05-07 20:01:0114759 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]8e6441ca2010-08-19 05:56:3814760 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0714761 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3814762
[email protected]49639fa2011-12-20 23:22:4114763 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3814764
vishal.b62985ca92015-04-17 08:45:5114765 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4114766 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114767 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3814768 trans.reset(); // Cancel the transaction here.
14769
fdoray92e35a72016-06-10 15:54:5514770 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3014771}
14772
[email protected]ecab6e052014-05-16 14:58:1214773// Test that if a transaction is cancelled after receiving the headers, the
14774// stream is drained properly and added back to the socket pool. The main
14775// purpose of this test is to make sure that an HttpStreamParser can be read
14776// from after the HttpNetworkTransaction and the objects it owns have been
14777// deleted.
14778// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0114779TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1214780 MockRead data_reads[] = {
14781 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
14782 MockRead(ASYNC, "Content-Length: 2\r\n"),
14783 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
14784 MockRead(ASYNC, "1"),
14785 // 2 async reads are necessary to trigger a ReadResponseBody call after the
14786 // HttpNetworkTransaction has been deleted.
14787 MockRead(ASYNC, "2"),
14788 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
14789 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114790 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]ecab6e052014-05-16 14:58:1214791 session_deps_.socket_factory->AddSocketDataProvider(&data);
14792
danakj1fd259a02016-04-16 03:17:0914793 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1214794
14795 {
14796 HttpRequestInfo request;
14797 request.method = "GET";
bncce36dca22015-04-21 22:11:2314798 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014799 request.traffic_annotation =
14800 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1214801
dcheng48459ac22014-08-26 00:46:4114802 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1214803 TestCompletionCallback callback;
14804
tfarina42834112016-09-22 13:38:2014805 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114806 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1214807 callback.WaitForResult();
14808
14809 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214810 ASSERT_TRUE(response);
14811 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1214812 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14813
14814 // The transaction and HttpRequestInfo are deleted.
14815 }
14816
14817 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5514818 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1214819
14820 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4114821 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1214822}
14823
[email protected]76a505b2010-08-25 06:23:0014824// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0114825TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914826 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914827 ProxyResolutionService::CreateFixedFromPacResult(
14828 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114829 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714830 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914831 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014832
[email protected]76a505b2010-08-25 06:23:0014833 HttpRequestInfo request;
14834 request.method = "GET";
bncce36dca22015-04-21 22:11:2314835 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014836 request.traffic_annotation =
14837 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014838
14839 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2314840 MockWrite(
14841 "GET http://www.example.org/ HTTP/1.1\r\n"
14842 "Host: www.example.org\r\n"
14843 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014844 };
14845
14846 MockRead data_reads1[] = {
14847 MockRead("HTTP/1.1 200 OK\r\n"),
14848 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14849 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614850 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014851 };
14852
Ryan Sleevib8d7ea02018-05-07 20:01:0114853 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714854 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0014855
[email protected]49639fa2011-12-20 23:22:4114856 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014857
bnc691fda62016-08-12 00:43:1614858 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914859 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614860 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914861 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14862 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014863
bnc691fda62016-08-12 00:43:1614864 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114865 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014866
14867 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114868 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0014869
bnc691fda62016-08-12 00:43:1614870 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214871 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014872
14873 EXPECT_TRUE(response->headers->IsKeepAlive());
14874 EXPECT_EQ(200, response->headers->response_code());
14875 EXPECT_EQ(100, response->headers->GetContentLength());
14876 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714877 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14878 HostPortPair::FromString("myproxy:70")),
14879 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914880 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14881 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14882 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0014883 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2014884
14885 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614886 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014887 TestLoadTimingNotReusedWithPac(load_timing_info,
14888 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0014889}
14890
14891// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0114892TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914893 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914894 ProxyResolutionService::CreateFixedFromPacResult(
14895 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114896 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714897 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914898 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014899
[email protected]76a505b2010-08-25 06:23:0014900 HttpRequestInfo request;
14901 request.method = "GET";
bncce36dca22015-04-21 22:11:2314902 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014903 request.traffic_annotation =
14904 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014905
14906 // Since we have proxy, should try to establish tunnel.
14907 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714908 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14909 "Host: www.example.org:443\r\n"
14910 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014911
rsleevidb16bb02015-11-12 23:47:1714912 MockWrite("GET / HTTP/1.1\r\n"
14913 "Host: www.example.org\r\n"
14914 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014915 };
14916
14917 MockRead data_reads1[] = {
14918 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14919
14920 MockRead("HTTP/1.1 200 OK\r\n"),
14921 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14922 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614923 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014924 };
14925
Ryan Sleevib8d7ea02018-05-07 20:01:0114926 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714927 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614928 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714929 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014930
[email protected]49639fa2011-12-20 23:22:4114931 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014932
bnc691fda62016-08-12 00:43:1614933 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914934 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614935 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914936 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14937 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014938
bnc691fda62016-08-12 00:43:1614939 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014941
14942 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114943 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4614944 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014945 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014946 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014947 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14948 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014949 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014950 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014951 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14952 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014953
bnc691fda62016-08-12 00:43:1614954 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214955 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014956
14957 EXPECT_TRUE(response->headers->IsKeepAlive());
14958 EXPECT_EQ(200, response->headers->response_code());
14959 EXPECT_EQ(100, response->headers->GetContentLength());
14960 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14961 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714962 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14963 HostPortPair::FromString("myproxy:70")),
14964 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914965 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14966 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14967 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2014968
14969 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614970 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014971 TestLoadTimingNotReusedWithPac(load_timing_info,
14972 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0014973}
14974
rsleevidb16bb02015-11-12 23:47:1714975// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
14976// literal host.
bncd16676a2016-07-20 16:23:0114977TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5914978 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914979 ProxyResolutionService::CreateFixedFromPacResult(
14980 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714981 BoundTestNetLog log;
14982 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914983 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1714984
14985 HttpRequestInfo request;
14986 request.method = "GET";
Eric Romanda790f92018-11-07 19:17:1514987 request.url = GURL("https://[::2]:443/");
Ramin Halavatib5e433e2018-02-07 07:41:1014988 request.traffic_annotation =
14989 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714990
14991 // Since we have proxy, should try to establish tunnel.
14992 MockWrite data_writes1[] = {
Eric Romanda790f92018-11-07 19:17:1514993 MockWrite("CONNECT [::2]:443 HTTP/1.1\r\n"
14994 "Host: [::2]:443\r\n"
rsleevidb16bb02015-11-12 23:47:1714995 "Proxy-Connection: keep-alive\r\n\r\n"),
14996
14997 MockWrite("GET / HTTP/1.1\r\n"
Eric Romanda790f92018-11-07 19:17:1514998 "Host: [::2]\r\n"
rsleevidb16bb02015-11-12 23:47:1714999 "Connection: keep-alive\r\n\r\n"),
15000 };
15001
15002 MockRead data_reads1[] = {
15003 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15004
15005 MockRead("HTTP/1.1 200 OK\r\n"),
15006 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15007 MockRead("Content-Length: 100\r\n\r\n"),
15008 MockRead(SYNCHRONOUS, OK),
15009 };
15010
Ryan Sleevib8d7ea02018-05-07 20:01:0115011 StaticSocketDataProvider data1(data_reads1, data_writes1);
rsleevidb16bb02015-11-12 23:47:1715012 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15013 SSLSocketDataProvider ssl(ASYNC, OK);
15014 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15015
15016 TestCompletionCallback callback1;
15017
bnc691fda62016-08-12 00:43:1615018 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1715019
bnc691fda62016-08-12 00:43:1615020 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0115021 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1715022
15023 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0115024 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1715025 TestNetLogEntry::List entries;
15026 log.GetEntries(&entries);
15027 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0015028 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
15029 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1715030 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0015031 entries, pos,
15032 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
15033 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1715034
bnc691fda62016-08-12 00:43:1615035 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215036 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1715037
15038 EXPECT_TRUE(response->headers->IsKeepAlive());
15039 EXPECT_EQ(200, response->headers->response_code());
15040 EXPECT_EQ(100, response->headers->GetContentLength());
15041 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
15042 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4715043 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
15044 HostPortPair::FromString("myproxy:70")),
15045 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1715046
15047 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1615048 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1715049 TestLoadTimingNotReusedWithPac(load_timing_info,
15050 CONNECT_TIMING_HAS_SSL_TIMES);
15051}
15052
[email protected]76a505b2010-08-25 06:23:0015053// Test a basic HTTPS GET request through a proxy, but the server hangs up
15054// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0115055TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4915056 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
15057 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115058 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715059 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0915060 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0015061
[email protected]76a505b2010-08-25 06:23:0015062 HttpRequestInfo request;
15063 request.method = "GET";
bncce36dca22015-04-21 22:11:2315064 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015065 request.traffic_annotation =
15066 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0015067
15068 // Since we have proxy, should try to establish tunnel.
15069 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1715070 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15071 "Host: www.example.org:443\r\n"
15072 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0015073
rsleevidb16bb02015-11-12 23:47:1715074 MockWrite("GET / HTTP/1.1\r\n"
15075 "Host: www.example.org\r\n"
15076 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0015077 };
15078
15079 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0015080 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0615081 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0015082 };
15083
Ryan Sleevib8d7ea02018-05-07 20:01:0115084 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0715085 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0615086 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0715087 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0015088
[email protected]49639fa2011-12-20 23:22:4115089 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0015090
bnc691fda62016-08-12 00:43:1615091 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5015092
bnc691fda62016-08-12 00:43:1615093 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0115094 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0015095
15096 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0115097 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4615098 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4015099 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0015100 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0015101 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
15102 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0015103 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4015104 entries, pos,
mikecirone8b85c432016-09-08 19:11:0015105 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
15106 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0015107}
15108
[email protected]749eefa82010-09-13 22:14:0315109// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0115110TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
Ryan Hamilton0239aac2018-05-19 00:03:1315111 spdy::SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4915112 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115113 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0315114
Raul Tambre94493c652019-03-11 17:18:3515115 spdy::SpdySerializedFrame resp(
15116 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315117 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0315118 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115119 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0315120 };
15121
Ryan Sleevib8d7ea02018-05-07 20:01:0115122 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715123 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0315124
[email protected]8ddf8322012-02-23 18:08:0615125 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615126 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715127 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0315128
danakj1fd259a02016-04-16 03:17:0915129 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0315130
15131 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2315132 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4015133 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1115134 PRIVACY_MODE_DISABLED,
15135 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2715136 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5215137 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0315138
15139 HttpRequestInfo request;
15140 request.method = "GET";
bncce36dca22015-04-21 22:11:2315141 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015142 request.traffic_annotation =
15143 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0315144
bnc691fda62016-08-12 00:43:1615145 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0315146
[email protected]41d64e82013-07-03 22:44:2615147 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015148 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115149 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15150 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0315151}
15152
[email protected]73b8dd222010-11-11 19:55:2415153// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1615154// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0215155void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0715156 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2915157 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715158 request_info.url = GURL("https://www.example.com/");
15159 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915160 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015161 request_info.traffic_annotation =
15162 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715163
[email protected]8ddf8322012-02-23 18:08:0615164 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2915165 MockWrite data_writes[] = {
15166 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2415167 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115168 StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
[email protected]bb88e1d32013-05-03 23:11:0715169 session_deps_.socket_factory->AddSocketDataProvider(&data);
15170 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2415171
danakj1fd259a02016-04-16 03:17:0915172 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615173 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2415174
[email protected]49639fa2011-12-20 23:22:4115175 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015176 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2915177 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2415178 rv = callback.WaitForResult();
15179 ASSERT_EQ(error, rv);
15180}
15181
bncd16676a2016-07-20 16:23:0115182TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2415183 // Just check a grab bag of cert errors.
15184 static const int kErrors[] = {
15185 ERR_CERT_COMMON_NAME_INVALID,
15186 ERR_CERT_AUTHORITY_INVALID,
15187 ERR_CERT_DATE_INVALID,
15188 };
Avi Drissman4365a4782018-12-28 19:26:2415189 for (size_t i = 0; i < base::size(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0615190 CheckErrorIsPassedBack(kErrors[i], ASYNC);
15191 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2415192 }
15193}
15194
[email protected]bd0b6772011-01-11 19:59:3015195// Ensure that a client certificate is removed from the SSL client auth
15196// cache when:
15197// 1) No proxy is involved.
15198// 2) TLS False Start is disabled.
15199// 3) The initial TLS handshake requests a client certificate.
15200// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115201TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915202 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715203 request_info.url = GURL("https://www.example.com/");
15204 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915205 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015206 request_info.traffic_annotation =
15207 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715208
[email protected]bd0b6772011-01-11 19:59:3015209 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115210 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015211
15212 // [ssl_]data1 contains the data for the first SSL handshake. When a
15213 // CertificateRequest is received for the first time, the handshake will
15214 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2915215 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015216 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715217 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115218 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715219 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015220
15221 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
15222 // False Start is not being used, the result of the SSL handshake will be
15223 // returned as part of the SSLClientSocket::Connect() call. This test
15224 // matches the result of a server sending a handshake_failure alert,
15225 // rather than a Finished message, because it requires a client
15226 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2915227 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3015228 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715229 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115230 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715231 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015232
15233 // [ssl_]data3 contains the data for the third SSL handshake. When a
15234 // connection to a server fails during an SSL handshake,
Steven Valdez0ef94d02018-11-19 23:28:1315235 // HttpNetworkTransaction will attempt to fallback to TLSv1.2 if the previous
15236 // connection was attempted with TLSv1.3. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3015237 // of the HttpNetworkTransaction. Because this test failure is due to
15238 // requiring a client certificate, this fallback handshake should also
15239 // fail.
ttuttle859dc7a2015-04-23 19:42:2915240 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
Steven Valdez0ef94d02018-11-19 23:28:1315241 ssl_data3.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
[email protected]bd0b6772011-01-11 19:59:3015242 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715243 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115244 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715245 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015246
[email protected]80c75f682012-05-26 16:22:1715247 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
15248 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4215249 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
15250 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1715251 // of the HttpNetworkTransaction. Because this test failure is due to
15252 // requiring a client certificate, this fallback handshake should also
15253 // fail.
ttuttle859dc7a2015-04-23 19:42:2915254 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1715255 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715256 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115257 StaticSocketDataProvider data4;
[email protected]bb88e1d32013-05-03 23:11:0715258 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715259
danakj1fd259a02016-04-16 03:17:0915260 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615261 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015262
[email protected]bd0b6772011-01-11 19:59:3015263 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4115264 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015265 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115266 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015267
15268 // Complete the SSL handshake, which should abort due to requiring a
15269 // client certificate.
15270 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115271 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015272
15273 // Indicate that no certificate should be supplied. From the perspective
15274 // of SSLClientCertCache, NULL is just as meaningful as a real
15275 // certificate, so this is the same as supply a
15276 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515277 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115278 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015279
15280 // Ensure the certificate was added to the client auth cache before
15281 // allowing the connection to continue restarting.
15282 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415283 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115284 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415285 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215286 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015287
15288 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715289 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15290 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015291 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115292 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015293
15294 // Ensure that the client certificate is removed from the cache on a
15295 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115296 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415297 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015298}
15299
15300// Ensure that a client certificate is removed from the SSL client auth
15301// cache when:
15302// 1) No proxy is involved.
15303// 2) TLS False Start is enabled.
15304// 3) The initial TLS handshake requests a client certificate.
15305// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115306TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915307 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715308 request_info.url = GURL("https://www.example.com/");
15309 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915310 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015311 request_info.traffic_annotation =
15312 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715313
[email protected]bd0b6772011-01-11 19:59:3015314 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115315 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015316
15317 // When TLS False Start is used, SSLClientSocket::Connect() calls will
15318 // return successfully after reading up to the peer's Certificate message.
15319 // This is to allow the caller to call SSLClientSocket::Write(), which can
15320 // enqueue application data to be sent in the same packet as the
15321 // ChangeCipherSpec and Finished messages.
15322 // The actual handshake will be finished when SSLClientSocket::Read() is
15323 // called, which expects to process the peer's ChangeCipherSpec and
15324 // Finished messages. If there was an error negotiating with the peer,
15325 // such as due to the peer requiring a client certificate when none was
15326 // supplied, the alert sent by the peer won't be processed until Read() is
15327 // called.
15328
15329 // Like the non-False Start case, when a client certificate is requested by
15330 // the peer, the handshake is aborted during the Connect() call.
15331 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2915332 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015333 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715334 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115335 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715336 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015337
15338 // When a client certificate is supplied, Connect() will not be aborted
15339 // when the peer requests the certificate. Instead, the handshake will
15340 // artificially succeed, allowing the caller to write the HTTP request to
15341 // the socket. The handshake messages are not processed until Read() is
15342 // called, which then detects that the handshake was aborted, due to the
15343 // peer sending a handshake_failure because it requires a client
15344 // certificate.
ttuttle859dc7a2015-04-23 19:42:2915345 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015346 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715347 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2915348 MockRead data2_reads[] = {
15349 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3015350 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115351 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715352 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015353
15354 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1715355 // the data for the SSL handshake once the TLSv1.1 connection falls back to
15356 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915357 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015358 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715359 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115360 StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715361 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015362
[email protected]80c75f682012-05-26 16:22:1715363 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
15364 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915365 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1715366 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115368 StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715369 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715370
[email protected]7799de12013-05-30 05:52:5115371 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2915372 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5115373 ssl_data5.cert_request_info = cert_request.get();
15374 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
Ryan Sleevib8d7ea02018-05-07 20:01:0115375 StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
[email protected]7799de12013-05-30 05:52:5115376 session_deps_.socket_factory->AddSocketDataProvider(&data5);
15377
danakj1fd259a02016-04-16 03:17:0915378 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615379 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015380
[email protected]bd0b6772011-01-11 19:59:3015381 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4115382 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015383 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115384 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015385
15386 // Complete the SSL handshake, which should abort due to requiring a
15387 // client certificate.
15388 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115389 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015390
15391 // Indicate that no certificate should be supplied. From the perspective
15392 // of SSLClientCertCache, NULL is just as meaningful as a real
15393 // certificate, so this is the same as supply a
15394 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515395 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115396 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015397
15398 // Ensure the certificate was added to the client auth cache before
15399 // allowing the connection to continue restarting.
15400 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415401 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115402 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415403 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215404 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015405
[email protected]bd0b6772011-01-11 19:59:3015406 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715407 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15408 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015409 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115410 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015411
15412 // Ensure that the client certificate is removed from the cache on a
15413 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115414 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415415 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015416}
15417
[email protected]8c405132011-01-11 22:03:1815418// Ensure that a client certificate is removed from the SSL client auth
15419// cache when:
15420// 1) An HTTPS proxy is involved.
15421// 3) The HTTPS proxy requests a client certificate.
15422// 4) The client supplies an invalid/unacceptable certificate for the
15423// proxy.
15424// The test is repeated twice, first for connecting to an HTTPS endpoint,
15425// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0115426TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4915427 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
15428 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115429 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715430 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1815431
15432 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115433 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1815434
15435 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
15436 // [ssl_]data[1-3]. Rather than represending the endpoint
15437 // (www.example.com:443), they represent failures with the HTTPS proxy
15438 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2915439 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1815440 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715441 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115442 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715443 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1815444
ttuttle859dc7a2015-04-23 19:42:2915445 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815446 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715447 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115448 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715449 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1815450
[email protected]80c75f682012-05-26 16:22:1715451 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
15452#if 0
ttuttle859dc7a2015-04-23 19:42:2915453 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815454 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715455 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115456 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715457 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1715458#endif
[email protected]8c405132011-01-11 22:03:1815459
ttuttle859dc7a2015-04-23 19:42:2915460 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1815461 requests[0].url = GURL("https://www.example.com/");
15462 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915463 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015464 requests[0].traffic_annotation =
15465 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815466
15467 requests[1].url = GURL("http://www.example.com/");
15468 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915469 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1015470 requests[1].traffic_annotation =
15471 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815472
Avi Drissman4365a4782018-12-28 19:26:2415473 for (size_t i = 0; i < base::size(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0715474 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0915475 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615476 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1815477
15478 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4115479 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015480 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115481 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815482
15483 // Complete the SSL handshake, which should abort due to requiring a
15484 // client certificate.
15485 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115486 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1815487
15488 // Indicate that no certificate should be supplied. From the perspective
15489 // of SSLClientCertCache, NULL is just as meaningful as a real
15490 // certificate, so this is the same as supply a
15491 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515492 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115493 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815494
15495 // Ensure the certificate was added to the client auth cache before
15496 // allowing the connection to continue restarting.
15497 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415498 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115499 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415500 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215501 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1815502 // Ensure the certificate was NOT cached for the endpoint. This only
15503 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4115504 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415505 HostPortPair("www.example.com", 443), &client_cert,
15506 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815507
15508 // Restart the handshake. This will consume ssl_data2, which fails, and
15509 // then consume ssl_data3, which should also fail. The result code is
15510 // checked against what ssl_data3 should return.
15511 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115512 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1815513
15514 // Now that the new handshake has failed, ensure that the client
15515 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4115516 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415517 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4115518 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415519 HostPortPair("www.example.com", 443), &client_cert,
15520 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815521 }
15522}
15523
bncd16676a2016-07-20 16:23:0115524TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4615525 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915526 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915527 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615528
bnc032658ba2016-09-26 18:17:1515529 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615530
Ryan Hamilton0239aac2018-05-19 00:03:1315531 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915532 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815533 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315534 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715535 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615536 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115537 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615538 };
Ryan Hamilton0239aac2018-05-19 00:03:1315539 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515540 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315541 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115542 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315543 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515544 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315545 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115546 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615547 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115548 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15549 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315550 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615551 };
15552
eroman36d84e54432016-03-17 03:23:0215553 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215554 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115555 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715556 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615557
[email protected]aa22b242011-11-16 18:58:2915558 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615559 HttpRequestInfo request1;
15560 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315561 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615562 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015563 request1.traffic_annotation =
15564 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015565 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615566
tfarina42834112016-09-22 13:38:2015567 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115568 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15569 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615570
15571 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215572 ASSERT_TRUE(response);
15573 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215574 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615575
15576 std::string response_data;
robpercival214763f2016-07-01 23:27:0115577 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615578 EXPECT_EQ("hello!", response_data);
15579
bnca4d611d2016-09-22 19:55:3715580 // Preload mail.example.com into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315581 rv = session_deps_.host_resolver->LoadIntoCache(
15582 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115583 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615584
15585 HttpRequestInfo request2;
15586 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715587 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615588 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015589 request2.traffic_annotation =
15590 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015591 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615592
tfarina42834112016-09-22 13:38:2015593 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115594 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15595 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615596
15597 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215598 ASSERT_TRUE(response);
15599 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215600 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615601 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215602 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115603 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615604 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615605}
15606
bncd16676a2016-07-20 16:23:0115607TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0215608 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915609 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915610 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0215611
bnc032658ba2016-09-26 18:17:1515612 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0215613
Ryan Hamilton0239aac2018-05-19 00:03:1315614 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915615 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815616 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315617 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715618 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0215619 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115620 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0215621 };
Ryan Hamilton0239aac2018-05-19 00:03:1315622 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515623 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315624 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115625 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315626 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515627 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315628 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115629 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0215630 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115631 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15632 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315633 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0215634 };
15635
eroman36d84e54432016-03-17 03:23:0215636 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215637 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115638 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715639 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0215640
15641 TestCompletionCallback callback;
15642 HttpRequestInfo request1;
15643 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315644 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0215645 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015646 request1.traffic_annotation =
15647 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015648 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215649
tfarina42834112016-09-22 13:38:2015650 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15652 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215653
15654 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215655 ASSERT_TRUE(response);
15656 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215657 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215658
15659 std::string response_data;
robpercival214763f2016-07-01 23:27:0115660 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215661 EXPECT_EQ("hello!", response_data);
15662
15663 HttpRequestInfo request2;
15664 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715665 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0215666 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015667 request2.traffic_annotation =
15668 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015669 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215670
tfarina42834112016-09-22 13:38:2015671 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15673 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215674
15675 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215676 ASSERT_TRUE(response);
15677 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215678 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215679 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215680 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115681 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215682 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0215683}
15684
bnc8016c1f2017-03-31 02:11:2915685// Regression test for https://crbug.com/546991.
15686// The server might not be able to serve an IP pooled request, and might send a
15687// 421 Misdirected Request response status to indicate this.
15688// HttpNetworkTransaction should reset the request and retry without IP pooling.
15689TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
15690 // Two hosts resolve to the same IP address.
15691 const std::string ip_addr = "1.2.3.4";
15692 IPAddress ip;
15693 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15694 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15695
Jeremy Roman0579ed62017-08-29 15:56:1915696 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2915697 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15698 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15699
15700 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15701
15702 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315703 spdy::SpdySerializedFrame req1(
bnc8016c1f2017-03-31 02:11:2915704 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15705 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315706 spdy::SpdySerializedFrame req2(
bnc8016c1f2017-03-31 02:11:2915707 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315708 spdy::SpdySerializedFrame rst(
15709 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
bnc8016c1f2017-03-31 02:11:2915710 MockWrite writes1[] = {
15711 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15712 CreateMockWrite(rst, 6),
15713 };
15714
15715 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315716 spdy::SpdySerializedFrame resp1(
15717 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15718 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15719 spdy::SpdyHeaderBlock response_headers;
15720 response_headers[spdy::kHttp2StatusHeader] = "421";
15721 spdy::SpdySerializedFrame resp2(
bnc8016c1f2017-03-31 02:11:2915722 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
15723 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15724 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15725
15726 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115727 SequencedSocketData data1(connect1, reads1, writes1);
bnc8016c1f2017-03-31 02:11:2915728 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15729
15730 AddSSLSocketData();
15731
15732 // Retry the second request on a second connection.
15733 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315734 spdy::SpdySerializedFrame req3(
bnc8016c1f2017-03-31 02:11:2915735 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15736 MockWrite writes2[] = {
15737 CreateMockWrite(req3, 0),
15738 };
15739
Ryan Hamilton0239aac2018-05-19 00:03:1315740 spdy::SpdySerializedFrame resp3(
15741 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
15742 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
bnc8016c1f2017-03-31 02:11:2915743 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15744 MockRead(ASYNC, 0, 3)};
15745
15746 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115747 SequencedSocketData data2(connect2, reads2, writes2);
bnc8016c1f2017-03-31 02:11:2915748 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15749
15750 AddSSLSocketData();
15751
15752 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315753 int rv = session_deps_.host_resolver->LoadIntoCache(
15754 HostPortPair("mail.example.com", 443), base::nullopt);
bnc8016c1f2017-03-31 02:11:2915755 EXPECT_THAT(rv, IsOk());
15756
15757 HttpRequestInfo request1;
15758 request1.method = "GET";
15759 request1.url = GURL("https://www.example.org/");
15760 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015761 request1.traffic_annotation =
15762 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915763 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15764
Eric Orthf4db66a2019-02-19 21:35:3315765 TestCompletionCallback callback;
bnc8016c1f2017-03-31 02:11:2915766 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15767 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15768 rv = callback.WaitForResult();
15769 EXPECT_THAT(rv, IsOk());
15770
15771 const HttpResponseInfo* response = trans1.GetResponseInfo();
15772 ASSERT_TRUE(response);
15773 ASSERT_TRUE(response->headers);
15774 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15775 EXPECT_TRUE(response->was_fetched_via_spdy);
15776 EXPECT_TRUE(response->was_alpn_negotiated);
15777 std::string response_data;
15778 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15779 EXPECT_EQ("hello!", response_data);
15780
15781 HttpRequestInfo request2;
15782 request2.method = "GET";
15783 request2.url = GURL("https://mail.example.org/");
15784 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015785 request2.traffic_annotation =
15786 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915787 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15788
15789 BoundTestNetLog log;
15790 rv = trans2.Start(&request2, callback.callback(), log.bound());
15791 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15792 rv = callback.WaitForResult();
15793 EXPECT_THAT(rv, IsOk());
15794
15795 response = trans2.GetResponseInfo();
15796 ASSERT_TRUE(response);
15797 ASSERT_TRUE(response->headers);
15798 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15799 EXPECT_TRUE(response->was_fetched_via_spdy);
15800 EXPECT_TRUE(response->was_alpn_negotiated);
15801 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15802 EXPECT_EQ("hello!", response_data);
15803
15804 TestNetLogEntry::List entries;
15805 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5915806 ExpectLogContainsSomewhere(
15807 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2915808 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5915809}
15810
15811// Test that HTTP 421 responses are properly returned to the caller if received
15812// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
15813// portions of the response.
15814TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
15815 // Two hosts resolve to the same IP address.
15816 const std::string ip_addr = "1.2.3.4";
15817 IPAddress ip;
15818 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15819 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15820
Jeremy Roman0579ed62017-08-29 15:56:1915821 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5915822 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15823 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15824
15825 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15826
15827 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315828 spdy::SpdySerializedFrame req1(
davidbence688ae2017-05-04 15:12:5915829 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15830 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315831 spdy::SpdySerializedFrame req2(
davidbence688ae2017-05-04 15:12:5915832 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315833 spdy::SpdySerializedFrame rst(
15834 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
davidbence688ae2017-05-04 15:12:5915835 MockWrite writes1[] = {
15836 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15837 CreateMockWrite(rst, 6),
15838 };
15839
15840 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315841 spdy::SpdySerializedFrame resp1(
15842 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15843 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15844 spdy::SpdyHeaderBlock response_headers;
15845 response_headers[spdy::kHttp2StatusHeader] = "421";
15846 spdy::SpdySerializedFrame resp2(
davidbence688ae2017-05-04 15:12:5915847 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
15848 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15849 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15850
15851 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115852 SequencedSocketData data1(connect1, reads1, writes1);
davidbence688ae2017-05-04 15:12:5915853 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15854
15855 AddSSLSocketData();
15856
15857 // Retry the second request on a second connection. It returns 421 Misdirected
15858 // Retry again.
15859 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315860 spdy::SpdySerializedFrame req3(
davidbence688ae2017-05-04 15:12:5915861 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15862 MockWrite writes2[] = {
15863 CreateMockWrite(req3, 0),
15864 };
15865
Ryan Hamilton0239aac2018-05-19 00:03:1315866 spdy::SpdySerializedFrame resp3(
davidbence688ae2017-05-04 15:12:5915867 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
Ryan Hamilton0239aac2018-05-19 00:03:1315868 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
davidbence688ae2017-05-04 15:12:5915869 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15870 MockRead(ASYNC, 0, 3)};
15871
15872 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115873 SequencedSocketData data2(connect2, reads2, writes2);
davidbence688ae2017-05-04 15:12:5915874 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15875
15876 AddSSLSocketData();
15877
15878 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315879 int rv = session_deps_.host_resolver->LoadIntoCache(
15880 HostPortPair("mail.example.com", 443), base::nullopt);
davidbence688ae2017-05-04 15:12:5915881 EXPECT_THAT(rv, IsOk());
15882
15883 HttpRequestInfo request1;
15884 request1.method = "GET";
15885 request1.url = GURL("https://www.example.org/");
15886 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015887 request1.traffic_annotation =
15888 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915889 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15890
Eric Orthf4db66a2019-02-19 21:35:3315891 TestCompletionCallback callback;
davidbence688ae2017-05-04 15:12:5915892 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15894 rv = callback.WaitForResult();
15895 EXPECT_THAT(rv, IsOk());
15896
15897 const HttpResponseInfo* response = trans1.GetResponseInfo();
15898 ASSERT_TRUE(response);
15899 ASSERT_TRUE(response->headers);
15900 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15901 EXPECT_TRUE(response->was_fetched_via_spdy);
15902 EXPECT_TRUE(response->was_alpn_negotiated);
15903 std::string response_data;
15904 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15905 EXPECT_EQ("hello!", response_data);
15906
15907 HttpRequestInfo request2;
15908 request2.method = "GET";
15909 request2.url = GURL("https://mail.example.org/");
15910 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015911 request2.traffic_annotation =
15912 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915913 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15914
15915 BoundTestNetLog log;
15916 rv = trans2.Start(&request2, callback.callback(), log.bound());
15917 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15918 rv = callback.WaitForResult();
15919 EXPECT_THAT(rv, IsOk());
15920
15921 // After a retry, the 421 Misdirected Request is reported back up to the
15922 // caller.
15923 response = trans2.GetResponseInfo();
15924 ASSERT_TRUE(response);
15925 ASSERT_TRUE(response->headers);
15926 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
15927 EXPECT_TRUE(response->was_fetched_via_spdy);
15928 EXPECT_TRUE(response->was_alpn_negotiated);
15929 EXPECT_TRUE(response->ssl_info.cert);
15930 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15931 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2915932}
15933
bncd16676a2016-07-20 16:23:0115934TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1315935 UseIPConnectionPoolingWithHostCacheExpiration) {
Eric Orth1da75de2019-02-20 21:10:3415936 // Set up HostResolver to invalidate cached entries after 1 cached resolve.
15937 session_deps_.host_resolver =
15938 std::make_unique<MockCachingHostResolver>(1 /* cache_invalidation_num */);
danakj1fd259a02016-04-16 03:17:0915939 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615940
bnc032658ba2016-09-26 18:17:1515941 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615942
Ryan Hamilton0239aac2018-05-19 00:03:1315943 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915944 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815945 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315946 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715947 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615948 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115949 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615950 };
Ryan Hamilton0239aac2018-05-19 00:03:1315951 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515952 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315953 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115954 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315955 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515956 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315957 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115958 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615959 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115960 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15961 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315962 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615963 };
15964
eroman36d84e54432016-03-17 03:23:0215965 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215966 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115967 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715968 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615969
[email protected]aa22b242011-11-16 18:58:2915970 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615971 HttpRequestInfo request1;
15972 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315973 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615974 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015975 request1.traffic_annotation =
15976 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015977 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615978
tfarina42834112016-09-22 13:38:2015979 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115980 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15981 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615982
15983 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215984 ASSERT_TRUE(response);
15985 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215986 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615987
15988 std::string response_data;
robpercival214763f2016-07-01 23:27:0115989 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615990 EXPECT_EQ("hello!", response_data);
15991
15992 // Preload cache entries into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315993 rv = session_deps_.host_resolver->LoadIntoCache(
15994 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115995 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615996
15997 HttpRequestInfo request2;
15998 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715999 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4616000 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016001 request2.traffic_annotation =
16002 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016003 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4616004
tfarina42834112016-09-22 13:38:2016005 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116006 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16007 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4616008
16009 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216010 ASSERT_TRUE(response);
16011 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216012 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4616013 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216014 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116015 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4616016 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4616017}
16018
bncd16676a2016-07-20 16:23:0116019TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2316020 const std::string https_url = "https://www.example.org:8080/";
16021 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0416022
16023 // SPDY GET for HTTPS URL
Ryan Hamilton0239aac2018-05-19 00:03:1316024 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4916025 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0416026
16027 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116028 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0416029 };
16030
Raul Tambre94493c652019-03-11 17:18:3516031 spdy::SpdySerializedFrame resp1(
16032 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316033 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4116034 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5916035 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0416036
Ryan Sleevib8d7ea02018-05-07 20:01:0116037 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0416038 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5716039 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0416040
16041 // HTTP GET for the HTTP URL
16042 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1316043 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3416044 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316045 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3416046 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0416047 };
16048
16049 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1316050 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
16051 MockRead(ASYNC, 2, "hello"),
16052 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0416053 };
16054
Ryan Sleevib8d7ea02018-05-07 20:01:0116055 SequencedSocketData data2(reads2, writes2);
[email protected]8450d722012-07-02 19:14:0416056
[email protected]8450d722012-07-02 19:14:0416057 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616058 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0716059 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16060 session_deps_.socket_factory->AddSocketDataProvider(&data1);
16061 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0416062
danakj1fd259a02016-04-16 03:17:0916063 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0416064
16065 // Start the first transaction to set up the SpdySession
16066 HttpRequestInfo request1;
16067 request1.method = "GET";
16068 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0416069 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016070 request1.traffic_annotation =
16071 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016072 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0416073 TestCompletionCallback callback1;
16074 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016075 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516076 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0416077
robpercival214763f2016-07-01 23:27:0116078 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0416079 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16080
16081 // Now, start the HTTP request
16082 HttpRequestInfo request2;
16083 request2.method = "GET";
16084 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0416085 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016086 request2.traffic_annotation =
16087 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016088 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0416089 TestCompletionCallback callback2;
16090 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016091 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516092 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0416093
robpercival214763f2016-07-01 23:27:0116094 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0416095 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16096}
16097
bnc5452e2a2015-05-08 16:27:4216098// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
16099// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0116100TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2516101 url::SchemeHostPort server("https", "www.example.org", 443);
16102 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4216103
bnc8bef8da22016-05-30 01:28:2516104 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4216105 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616106 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216107 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16108
16109 // No data should be read from the alternative, because HTTP/1.1 is
16110 // negotiated.
16111 StaticSocketDataProvider data;
16112 session_deps_.socket_factory->AddSocketDataProvider(&data);
16113
16114 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4616115 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4216116 // mocked. This way the request relies on the alternate Job.
16117 StaticSocketDataProvider data_refused;
16118 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16119 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16120
zhongyi3d4a55e72016-04-22 20:36:4616121 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916122 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016123 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216124 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116125 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216126 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116127 http_server_properties->SetHttp2AlternativeService(
16128 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216129
bnc5452e2a2015-05-08 16:27:4216130 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4616131 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216132 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2516133 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e2018-02-07 07:41:1016134 request.traffic_annotation =
16135 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216136 TestCompletionCallback callback;
16137
16138 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5216139 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2016140 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5216141 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4216142}
16143
bnc40448a532015-05-11 19:13:1416144// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4616145// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1416146// succeeds, the request should succeed, even if the latter fails because
16147// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0116148TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2516149 url::SchemeHostPort server("https", "www.example.org", 443);
16150 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1416151
16152 // Negotiate HTTP/1.1 with alternative.
16153 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616154 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416155 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
16156
16157 // No data should be read from the alternative, because HTTP/1.1 is
16158 // negotiated.
16159 StaticSocketDataProvider data;
16160 session_deps_.socket_factory->AddSocketDataProvider(&data);
16161
zhongyi3d4a55e72016-04-22 20:36:4616162 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1416163 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616164 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416165 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
16166
16167 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2516168 MockWrite("GET / HTTP/1.1\r\n"
16169 "Host: www.example.org\r\n"
16170 "Connection: keep-alive\r\n\r\n"),
16171 MockWrite("GET /second HTTP/1.1\r\n"
16172 "Host: www.example.org\r\n"
16173 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1416174 };
16175
16176 MockRead http_reads[] = {
16177 MockRead("HTTP/1.1 200 OK\r\n"),
16178 MockRead("Content-Type: text/html\r\n"),
16179 MockRead("Content-Length: 6\r\n\r\n"),
16180 MockRead("foobar"),
16181 MockRead("HTTP/1.1 200 OK\r\n"),
16182 MockRead("Content-Type: text/html\r\n"),
16183 MockRead("Content-Length: 7\r\n\r\n"),
16184 MockRead("another"),
16185 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116186 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc40448a532015-05-11 19:13:1416187 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16188
zhongyi3d4a55e72016-04-22 20:36:4616189 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916190 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016191 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1416192 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116193 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216194 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116195 http_server_properties->SetHttp2AlternativeService(
16196 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1416197
16198 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
16199 HttpRequestInfo request1;
16200 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2516201 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1416202 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016203 request1.traffic_annotation =
16204 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416205 TestCompletionCallback callback1;
16206
tfarina42834112016-09-22 13:38:2016207 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416208 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116209 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416210
16211 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5216212 ASSERT_TRUE(response1);
16213 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1416214 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
16215
16216 std::string response_data1;
robpercival214763f2016-07-01 23:27:0116217 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1416218 EXPECT_EQ("foobar", response_data1);
16219
16220 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
16221 // for alternative service.
16222 EXPECT_TRUE(
16223 http_server_properties->IsAlternativeServiceBroken(alternative_service));
16224
zhongyi3d4a55e72016-04-22 20:36:4616225 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1416226 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4616227 // to server.
bnc40448a532015-05-11 19:13:1416228 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
16229 HttpRequestInfo request2;
16230 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2516231 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1416232 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016233 request2.traffic_annotation =
16234 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416235 TestCompletionCallback callback2;
16236
tfarina42834112016-09-22 13:38:2016237 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416238 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116239 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416240
16241 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216242 ASSERT_TRUE(response2);
16243 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1416244 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
16245
16246 std::string response_data2;
robpercival214763f2016-07-01 23:27:0116247 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1416248 EXPECT_EQ("another", response_data2);
16249}
16250
bnc5452e2a2015-05-08 16:27:4216251// Alternative service requires HTTP/2 (or SPDY), but there is already a
16252// HTTP/1.1 socket open to the alternative server. That socket should not be
16253// used.
bncd16676a2016-07-20 16:23:0116254TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4616255 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4216256 HostPortPair alternative("alternative.example.org", 443);
16257 std::string origin_url = "https://origin.example.org:443";
16258 std::string alternative_url = "https://alternative.example.org:443";
16259
16260 // Negotiate HTTP/1.1 with alternative.example.org.
16261 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616262 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216263 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16264
16265 // HTTP/1.1 data for |request1| and |request2|.
16266 MockWrite http_writes[] = {
16267 MockWrite(
16268 "GET / HTTP/1.1\r\n"
16269 "Host: alternative.example.org\r\n"
16270 "Connection: keep-alive\r\n\r\n"),
16271 MockWrite(
16272 "GET / HTTP/1.1\r\n"
16273 "Host: alternative.example.org\r\n"
16274 "Connection: keep-alive\r\n\r\n"),
16275 };
16276
16277 MockRead http_reads[] = {
16278 MockRead(
16279 "HTTP/1.1 200 OK\r\n"
16280 "Content-Type: text/html; charset=iso-8859-1\r\n"
16281 "Content-Length: 40\r\n\r\n"
16282 "first HTTP/1.1 response from alternative"),
16283 MockRead(
16284 "HTTP/1.1 200 OK\r\n"
16285 "Content-Type: text/html; charset=iso-8859-1\r\n"
16286 "Content-Length: 41\r\n\r\n"
16287 "second HTTP/1.1 response from alternative"),
16288 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116289 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc5452e2a2015-05-08 16:27:4216290 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16291
16292 // This test documents that an alternate Job should not pool to an already
16293 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4616294 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4216295 StaticSocketDataProvider data_refused;
16296 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16297 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16298
zhongyi3d4a55e72016-04-22 20:36:4616299 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916300 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016301 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216302 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116303 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216304 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116305 http_server_properties->SetHttp2AlternativeService(
16306 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216307
16308 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4216309 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4616310 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216311 request1.method = "GET";
16312 request1.url = GURL(alternative_url);
16313 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016314 request1.traffic_annotation =
16315 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216316 TestCompletionCallback callback1;
16317
tfarina42834112016-09-22 13:38:2016318 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116319 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616320 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216321 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5216322 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4216323 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216324 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216325 EXPECT_FALSE(response1->was_fetched_via_spdy);
16326 std::string response_data1;
bnc691fda62016-08-12 00:43:1616327 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4216328 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
16329
16330 // Request for origin.example.org, which has an alternative service. This
16331 // will start two Jobs: the alternative looks for connections to pool to,
16332 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4616333 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4216334 // this request fails.
bnc5452e2a2015-05-08 16:27:4216335 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4616336 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216337 request2.method = "GET";
16338 request2.url = GURL(origin_url);
16339 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016340 request2.traffic_annotation =
16341 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216342 TestCompletionCallback callback2;
16343
tfarina42834112016-09-22 13:38:2016344 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116345 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4216346
16347 // Another transaction to alternative. This is to test that the HTTP/1.1
16348 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4216349 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4616350 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216351 request3.method = "GET";
16352 request3.url = GURL(alternative_url);
16353 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016354 request3.traffic_annotation =
16355 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216356 TestCompletionCallback callback3;
16357
tfarina42834112016-09-22 13:38:2016358 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116359 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616360 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216361 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5216362 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4216363 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216364 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216365 EXPECT_FALSE(response3->was_fetched_via_spdy);
16366 std::string response_data3;
bnc691fda62016-08-12 00:43:1616367 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4216368 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
16369}
16370
bncd16676a2016-07-20 16:23:0116371TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2316372 const std::string https_url = "https://www.example.org:8080/";
16373 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0416374
rdsmithebb50aa2015-11-12 03:44:3816375 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0116376 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3816377
[email protected]8450d722012-07-02 19:14:0416378 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2316379 const HostPortPair host_port_pair("www.example.org", 8080);
Matt Menke6e879bd2019-03-18 17:26:0416380 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
16381 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
16382 host_port_pair));
Ryan Hamilton0239aac2018-05-19 00:03:1316383 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4916384 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1316385 spdy::SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0216386 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3916387
16388 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
Ryan Hamilton0239aac2018-05-19 00:03:1316389 spdy::SpdyHeaderBlock req2_block;
16390 req2_block[spdy::kHttp2MethodHeader] = "GET";
16391 req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
16392 req2_block[spdy::kHttp2SchemeHeader] = "http";
16393 req2_block[spdy::kHttp2PathHeader] = "/";
16394 spdy::SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1516395 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0416396
16397 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116398 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
16399 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0416400 };
16401
Ryan Hamilton0239aac2018-05-19 00:03:1316402 spdy::SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1516403 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316404 spdy::SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1516405 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316406 spdy::SpdySerializedFrame body1(
16407 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
16408 spdy::SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3816409 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316410 spdy::SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3816411 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
Raul Tambre94493c652019-03-11 17:18:3516412 spdy::SpdySerializedFrame resp2(
16413 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1316414 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3316415 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116416 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3316417 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4116418 CreateMockRead(wrapped_resp1, 4),
16419 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3316420 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4116421 CreateMockRead(resp2, 8),
16422 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3316423 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
16424 };
[email protected]8450d722012-07-02 19:14:0416425
Ryan Sleevib8d7ea02018-05-07 20:01:0116426 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0416427 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5716428 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0416429
Lily Houghton8c2f97d2018-01-22 05:06:5916430 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916431 ProxyResolutionService::CreateFixedFromPacResult(
16432 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5116433 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0716434 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0416435 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616436 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316437 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0416438 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616439 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316440 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16441 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0416442
danakj1fd259a02016-04-16 03:17:0916443 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0416444
16445 // Start the first transaction to set up the SpdySession
16446 HttpRequestInfo request1;
16447 request1.method = "GET";
16448 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0416449 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016450 request1.traffic_annotation =
16451 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016452 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0416453 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2016454 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416455
mmenke666a6fea2015-12-19 04:16:3316456 // This pause is a hack to avoid running into https://crbug.com/497228.
16457 data1.RunUntilPaused();
16458 base::RunLoop().RunUntilIdle();
16459 data1.Resume();
robpercival214763f2016-07-01 23:27:0116460 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0416461 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16462
[email protected]f6c63db52013-02-02 00:35:2216463 LoadTimingInfo load_timing_info1;
16464 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
16465 TestLoadTimingNotReusedWithPac(load_timing_info1,
16466 CONNECT_TIMING_HAS_SSL_TIMES);
16467
mmenke666a6fea2015-12-19 04:16:3316468 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0416469 HttpRequestInfo request2;
16470 request2.method = "GET";
16471 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0416472 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016473 request2.traffic_annotation =
16474 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016475 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0416476 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2016477 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416478
mmenke666a6fea2015-12-19 04:16:3316479 // This pause is a hack to avoid running into https://crbug.com/497228.
16480 data1.RunUntilPaused();
16481 base::RunLoop().RunUntilIdle();
16482 data1.Resume();
robpercival214763f2016-07-01 23:27:0116483 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3316484
[email protected]8450d722012-07-02 19:14:0416485 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2216486
16487 LoadTimingInfo load_timing_info2;
16488 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
16489 // The established SPDY sessions is considered reused by the HTTP request.
16490 TestLoadTimingReusedWithPac(load_timing_info2);
16491 // HTTP requests over a SPDY session should have a different connection
16492 // socket_log_id than requests over a tunnel.
16493 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0416494}
16495
[email protected]2d88e7d2012-07-19 17:55:1716496// Test that in the case where we have a SPDY session to a SPDY proxy
16497// that we do not pool other origins that resolve to the same IP when
16498// the certificate does not match the new origin.
16499// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0116500TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2316501 const std::string url1 = "http://www.example.org/";
16502 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1716503 const std::string ip_addr = "1.2.3.4";
16504
rdsmithebb50aa2015-11-12 03:44:3816505 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0116506 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3816507
[email protected]2d88e7d2012-07-19 17:55:1716508 // SPDY GET for HTTP URL (through SPDY proxy)
Ryan Hamilton0239aac2018-05-19 00:03:1316509 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2316510 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:1316511 spdy::SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1516512 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1716513
16514 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116515 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1716516 };
16517
Raul Tambre94493c652019-03-11 17:18:3516518 spdy::SpdySerializedFrame resp1(
16519 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316520 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1716521 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116522 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
16523 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1716524 };
16525
Ryan Sleevib8d7ea02018-05-07 20:01:0116526 SequencedSocketData data1(reads1, writes1);
martijnfe9636e2016-02-06 14:33:3216527 IPAddress ip;
martijn654c8c42016-02-10 22:10:5916528 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1716529 IPEndPoint peer_addr = IPEndPoint(ip, 443);
16530 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3316531 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1716532
16533 // SPDY GET for HTTPS URL (direct)
Ryan Hamilton0239aac2018-05-19 00:03:1316534 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916535 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1716536
16537 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116538 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1716539 };
16540
Ryan Hamilton0239aac2018-05-19 00:03:1316541 spdy::SpdySerializedFrame resp2(
Raul Tambre94493c652019-03-11 17:18:3516542 spdy_util_secure.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316543 spdy::SpdySerializedFrame body2(
16544 spdy_util_secure.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4116545 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3316546 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1716547
Ryan Sleevib8d7ea02018-05-07 20:01:0116548 SequencedSocketData data2(reads2, writes2);
[email protected]2d88e7d2012-07-19 17:55:1716549 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3316550 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1716551
16552 // Set up a proxy config that sends HTTP requests to a proxy, and
16553 // all others direct.
16554 ProxyConfig proxy_config;
16555 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4916556 session_deps_.proxy_resolution_service =
16557 std::make_unique<ProxyResolutionService>(
16558 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
16559 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
16560 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1716561
bncce36dca22015-04-21 22:11:2316562 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616563 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1716564 // Load a valid cert. Note, that this does not need to
16565 // be valid for proxy because the MockSSLClientSocket does
16566 // not actually verify it. But SpdySession will use this
16567 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4916568 ssl1.ssl_info.cert =
16569 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
16570 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3316571 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16572 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1716573
16574 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616575 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316576 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16577 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1716578
Jeremy Roman0579ed62017-08-29 15:56:1916579 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2316580 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0716581 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1716582
danakj1fd259a02016-04-16 03:17:0916583 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1716584
16585 // Start the first transaction to set up the SpdySession
16586 HttpRequestInfo request1;
16587 request1.method = "GET";
16588 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1716589 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016590 request1.traffic_annotation =
16591 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016592 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716593 TestCompletionCallback callback1;
16594 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016595 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3316596 // This pause is a hack to avoid running into https://crbug.com/497228.
16597 data1.RunUntilPaused();
16598 base::RunLoop().RunUntilIdle();
16599 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1716600
robpercival214763f2016-07-01 23:27:0116601 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716602 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16603
16604 // Now, start the HTTP request
16605 HttpRequestInfo request2;
16606 request2.method = "GET";
16607 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1716608 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016609 request2.traffic_annotation =
16610 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016611 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716612 TestCompletionCallback callback2;
16613 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016614 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516615 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1716616
16617 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0116618 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716619 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16620}
16621
[email protected]85f97342013-04-17 06:12:2416622// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
16623// error) in SPDY session, removes the socket from pool and closes the SPDY
16624// session. Verify that new url's from the same HttpNetworkSession (and a new
16625// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0116626TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2316627 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2416628
16629 MockRead reads1[] = {
16630 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
16631 };
16632
Ryan Sleevib8d7ea02018-05-07 20:01:0116633 SequencedSocketData data1(reads1, base::span<MockWrite>());
[email protected]85f97342013-04-17 06:12:2416634
Ryan Hamilton0239aac2018-05-19 00:03:1316635 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916636 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2416637 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116638 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2416639 };
16640
Raul Tambre94493c652019-03-11 17:18:3516641 spdy::SpdySerializedFrame resp2(
16642 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316643 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2416644 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4116645 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
16646 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2416647 };
16648
Ryan Sleevib8d7ea02018-05-07 20:01:0116649 SequencedSocketData data2(reads2, writes2);
[email protected]85f97342013-04-17 06:12:2416650
[email protected]85f97342013-04-17 06:12:2416651 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616652 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016653 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16654 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2416655
16656 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616657 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016658 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16659 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2416660
danakj1fd259a02016-04-16 03:17:0916661 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5016662 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2416663
16664 // Start the first transaction to set up the SpdySession and verify that
16665 // connection was closed.
16666 HttpRequestInfo request1;
16667 request1.method = "GET";
16668 request1.url = GURL(https_url);
16669 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016670 request1.traffic_annotation =
16671 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016672 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416673 TestCompletionCallback callback1;
16674 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016675 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116676 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2416677
16678 // Now, start the second request and make sure it succeeds.
16679 HttpRequestInfo request2;
16680 request2.method = "GET";
16681 request2.url = GURL(https_url);
16682 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016683 request2.traffic_annotation =
16684 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016685 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416686 TestCompletionCallback callback2;
16687 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016688 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2416689
robpercival214763f2016-07-01 23:27:0116690 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2416691 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16692}
16693
bncd16676a2016-07-20 16:23:0116694TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0316695 ClientSocketPoolManager::set_max_sockets_per_group(
16696 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16697 ClientSocketPoolManager::set_max_sockets_per_pool(
16698 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16699
16700 // Use two different hosts with different IPs so they don't get pooled.
16701 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
16702 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0916703 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0316704
16705 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616706 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316707 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616708 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316709 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16710 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16711
Ryan Hamilton0239aac2018-05-19 00:03:1316712 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4916713 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316714 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116715 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0316716 };
Ryan Hamilton0239aac2018-05-19 00:03:1316717 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3516718 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316719 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4116720 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316721 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116722 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916723 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316724 };
16725
rdsmithebb50aa2015-11-12 03:44:3816726 // Use a separate test instance for the separate SpdySession that will be
16727 // created.
bncd16676a2016-07-20 16:23:0116728 SpdyTestUtil spdy_util_2;
Ryan Sleevib8d7ea02018-05-07 20:01:0116729 SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
Bence Béky53a5aef2018-03-29 21:54:1216730 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0316731
Ryan Hamilton0239aac2018-05-19 00:03:1316732 spdy::SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4916733 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316734 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116735 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0316736 };
Ryan Hamilton0239aac2018-05-19 00:03:1316737 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3516738 spdy_util_2.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316739 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4116740 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316741 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116742 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916743 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316744 };
16745
Ryan Sleevib8d7ea02018-05-07 20:01:0116746 SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
Bence Béky53a5aef2018-03-29 21:54:1216747 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0316748
16749 MockWrite http_write[] = {
16750 MockWrite("GET / HTTP/1.1\r\n"
16751 "Host: www.a.com\r\n"
16752 "Connection: keep-alive\r\n\r\n"),
16753 };
16754
16755 MockRead http_read[] = {
16756 MockRead("HTTP/1.1 200 OK\r\n"),
16757 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16758 MockRead("Content-Length: 6\r\n\r\n"),
16759 MockRead("hello!"),
16760 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116761 StaticSocketDataProvider http_data(http_read, http_write);
[email protected]483fa202013-05-14 01:07:0316762 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16763
16764 HostPortPair host_port_pair_a("www.a.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116765 SpdySessionKey spdy_session_key_a(
16766 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16767 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316768 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616769 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316770
16771 TestCompletionCallback callback;
16772 HttpRequestInfo request1;
16773 request1.method = "GET";
16774 request1.url = GURL("https://www.a.com/");
16775 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016776 request1.traffic_annotation =
16777 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816778 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916779 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316780
tfarina42834112016-09-22 13:38:2016781 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116782 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16783 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316784
16785 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216786 ASSERT_TRUE(response);
16787 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216788 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316789 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216790 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0316791
16792 std::string response_data;
robpercival214763f2016-07-01 23:27:0116793 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316794 EXPECT_EQ("hello!", response_data);
16795 trans.reset();
16796 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616797 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316798
16799 HostPortPair host_port_pair_b("www.b.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116800 SpdySessionKey spdy_session_key_b(
16801 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16802 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316803 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616804 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316805 HttpRequestInfo request2;
16806 request2.method = "GET";
16807 request2.url = GURL("https://www.b.com/");
16808 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016809 request2.traffic_annotation =
16810 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816811 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916812 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316813
tfarina42834112016-09-22 13:38:2016814 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116815 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16816 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316817
16818 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216819 ASSERT_TRUE(response);
16820 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216821 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316822 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216823 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116824 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316825 EXPECT_EQ("hello!", response_data);
16826 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616827 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316828 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616829 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316830
16831 HostPortPair host_port_pair_a1("www.a.com", 80);
Matt Menke2436b2f2018-12-11 18:07:1116832 SpdySessionKey spdy_session_key_a1(
16833 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16834 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316835 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616836 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0316837 HttpRequestInfo request3;
16838 request3.method = "GET";
16839 request3.url = GURL("http://www.a.com/");
16840 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016841 request3.traffic_annotation =
16842 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816843 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916844 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316845
tfarina42834112016-09-22 13:38:2016846 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116847 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16848 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316849
16850 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216851 ASSERT_TRUE(response);
16852 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0316853 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16854 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216855 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116856 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316857 EXPECT_EQ("hello!", response_data);
16858 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616859 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316860 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616861 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316862}
16863
bncd16676a2016-07-20 16:23:0116864TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416865 HttpRequestInfo request;
16866 request.method = "GET";
bncce36dca22015-04-21 22:11:2316867 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016868 request.traffic_annotation =
16869 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416870
danakj1fd259a02016-04-16 03:17:0916871 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616872 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416873
ttuttled9dbc652015-09-29 20:00:5916874 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416875 StaticSocketDataProvider data;
16876 data.set_connect_data(mock_connect);
16877 session_deps_.socket_factory->AddSocketDataProvider(&data);
16878
16879 TestCompletionCallback callback;
16880
tfarina42834112016-09-22 13:38:2016881 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116882 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416883
16884 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116885 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416886
[email protected]79e1fd62013-06-20 06:50:0416887 // We don't care whether this succeeds or fails, but it shouldn't crash.
16888 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616889 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716890
16891 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616892 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716893 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116894 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916895
16896 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616897 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916898 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416899}
16900
bncd16676a2016-07-20 16:23:0116901TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416902 HttpRequestInfo request;
16903 request.method = "GET";
bncce36dca22015-04-21 22:11:2316904 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016905 request.traffic_annotation =
16906 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416907
danakj1fd259a02016-04-16 03:17:0916908 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616909 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416910
ttuttled9dbc652015-09-29 20:00:5916911 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416912 StaticSocketDataProvider data;
16913 data.set_connect_data(mock_connect);
16914 session_deps_.socket_factory->AddSocketDataProvider(&data);
16915
16916 TestCompletionCallback callback;
16917
tfarina42834112016-09-22 13:38:2016918 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116919 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416920
16921 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116922 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416923
[email protected]79e1fd62013-06-20 06:50:0416924 // We don't care whether this succeeds or fails, but it shouldn't crash.
16925 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616926 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716927
16928 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616929 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716930 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116931 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916932
16933 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616934 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916935 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416936}
16937
bncd16676a2016-07-20 16:23:0116938TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416939 HttpRequestInfo request;
16940 request.method = "GET";
bncce36dca22015-04-21 22:11:2316941 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016942 request.traffic_annotation =
16943 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416944
danakj1fd259a02016-04-16 03:17:0916945 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616946 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416947
16948 MockWrite data_writes[] = {
16949 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16950 };
16951 MockRead data_reads[] = {
16952 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16953 };
16954
Ryan Sleevib8d7ea02018-05-07 20:01:0116955 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416956 session_deps_.socket_factory->AddSocketDataProvider(&data);
16957
16958 TestCompletionCallback callback;
16959
tfarina42834112016-09-22 13:38:2016960 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116961 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416962
16963 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116964 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416965
[email protected]79e1fd62013-06-20 06:50:0416966 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616967 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416968 EXPECT_TRUE(request_headers.HasHeader("Host"));
16969}
16970
bncd16676a2016-07-20 16:23:0116971TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416972 HttpRequestInfo request;
16973 request.method = "GET";
bncce36dca22015-04-21 22:11:2316974 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016975 request.traffic_annotation =
16976 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416977
danakj1fd259a02016-04-16 03:17:0916978 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616979 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416980
16981 MockWrite data_writes[] = {
16982 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16983 };
16984 MockRead data_reads[] = {
16985 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16986 };
16987
Ryan Sleevib8d7ea02018-05-07 20:01:0116988 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416989 session_deps_.socket_factory->AddSocketDataProvider(&data);
16990
16991 TestCompletionCallback callback;
16992
tfarina42834112016-09-22 13:38:2016993 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416995
16996 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116997 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416998
[email protected]79e1fd62013-06-20 06:50:0416999 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1617000 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0417001 EXPECT_TRUE(request_headers.HasHeader("Host"));
17002}
17003
bncd16676a2016-07-20 16:23:0117004TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0417005 HttpRequestInfo request;
17006 request.method = "GET";
bncce36dca22015-04-21 22:11:2317007 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017008 request.traffic_annotation =
17009 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0417010
danakj1fd259a02016-04-16 03:17:0917011 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617012 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0417013
17014 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2317015 MockWrite(
17016 "GET / HTTP/1.1\r\n"
17017 "Host: www.example.org\r\n"
17018 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0417019 };
17020 MockRead data_reads[] = {
17021 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
17022 };
17023
Ryan Sleevib8d7ea02018-05-07 20:01:0117024 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0417025 session_deps_.socket_factory->AddSocketDataProvider(&data);
17026
17027 TestCompletionCallback callback;
17028
tfarina42834112016-09-22 13:38:2017029 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117030 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0417031
17032 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117033 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0417034
[email protected]79e1fd62013-06-20 06:50:0417035 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1617036 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0417037 EXPECT_TRUE(request_headers.HasHeader("Host"));
17038}
17039
bncd16676a2016-07-20 16:23:0117040TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0417041 HttpRequestInfo request;
17042 request.method = "GET";
bncce36dca22015-04-21 22:11:2317043 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017044 request.traffic_annotation =
17045 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0417046
danakj1fd259a02016-04-16 03:17:0917047 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617048 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0417049
17050 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2317051 MockWrite(
17052 "GET / HTTP/1.1\r\n"
17053 "Host: www.example.org\r\n"
17054 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0417055 };
17056 MockRead data_reads[] = {
17057 MockRead(ASYNC, ERR_CONNECTION_RESET),
17058 };
17059
Ryan Sleevib8d7ea02018-05-07 20:01:0117060 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0417061 session_deps_.socket_factory->AddSocketDataProvider(&data);
17062
17063 TestCompletionCallback callback;
17064
tfarina42834112016-09-22 13:38:2017065 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117066 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0417067
17068 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117069 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0417070
[email protected]79e1fd62013-06-20 06:50:0417071 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1617072 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0417073 EXPECT_TRUE(request_headers.HasHeader("Host"));
17074}
17075
bncd16676a2016-07-20 16:23:0117076TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0417077 HttpRequestInfo request;
17078 request.method = "GET";
bncce36dca22015-04-21 22:11:2317079 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0417080 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1017081 request.traffic_annotation =
17082 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0417083
danakj1fd259a02016-04-16 03:17:0917084 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617085 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0417086
17087 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2317088 MockWrite(
17089 "GET / HTTP/1.1\r\n"
17090 "Host: www.example.org\r\n"
17091 "Connection: keep-alive\r\n"
17092 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0417093 };
17094 MockRead data_reads[] = {
17095 MockRead("HTTP/1.1 200 OK\r\n"
17096 "Content-Length: 5\r\n\r\n"
17097 "hello"),
17098 MockRead(ASYNC, ERR_UNEXPECTED),
17099 };
17100
Ryan Sleevib8d7ea02018-05-07 20:01:0117101 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0417102 session_deps_.socket_factory->AddSocketDataProvider(&data);
17103
17104 TestCompletionCallback callback;
17105
tfarina42834112016-09-22 13:38:2017106 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117107 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0417108
17109 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117110 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0417111
17112 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1617113 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0417114 std::string foo;
17115 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
17116 EXPECT_EQ("bar", foo);
17117}
17118
[email protected]043b68c82013-08-22 23:41:5217119// Tests that when a used socket is returned to the SSL socket pool, it's closed
17120// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117121TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5217122 ClientSocketPoolManager::set_max_sockets_per_group(
17123 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17124 ClientSocketPoolManager::set_max_sockets_per_pool(
17125 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17126
17127 // Set up SSL request.
17128
17129 HttpRequestInfo ssl_request;
17130 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2317131 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017132 ssl_request.traffic_annotation =
17133 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217134
17135 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2317136 MockWrite(
17137 "GET / HTTP/1.1\r\n"
17138 "Host: www.example.org\r\n"
17139 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217140 };
17141 MockRead ssl_reads[] = {
17142 MockRead("HTTP/1.1 200 OK\r\n"),
17143 MockRead("Content-Length: 11\r\n\r\n"),
17144 MockRead("hello world"),
17145 MockRead(SYNCHRONOUS, OK),
17146 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117147 StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
[email protected]043b68c82013-08-22 23:41:5217148 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17149
17150 SSLSocketDataProvider ssl(ASYNC, OK);
17151 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17152
17153 // Set up HTTP request.
17154
17155 HttpRequestInfo http_request;
17156 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317157 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017158 http_request.traffic_annotation =
17159 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217160
17161 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317162 MockWrite(
17163 "GET / HTTP/1.1\r\n"
17164 "Host: www.example.org\r\n"
17165 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217166 };
17167 MockRead http_reads[] = {
17168 MockRead("HTTP/1.1 200 OK\r\n"),
17169 MockRead("Content-Length: 7\r\n\r\n"),
17170 MockRead("falafel"),
17171 MockRead(SYNCHRONOUS, OK),
17172 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117173 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217174 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17175
danakj1fd259a02016-04-16 03:17:0917176 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217177
17178 // Start the SSL request.
17179 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1617180 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017181 ASSERT_EQ(ERR_IO_PENDING,
17182 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
17183 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5217184
17185 // Start the HTTP request. Pool should stall.
17186 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617187 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017188 ASSERT_EQ(ERR_IO_PENDING,
17189 http_trans.Start(&http_request, http_callback.callback(),
17190 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117191 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217192
17193 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0117194 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217195 std::string response_data;
bnc691fda62016-08-12 00:43:1617196 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217197 EXPECT_EQ("hello world", response_data);
17198
17199 // The SSL socket should automatically be closed, so the HTTP request can
17200 // start.
Matt Menke9d5e2c92019-02-05 01:42:2317201 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
dcheng48459ac22014-08-26 00:46:4117202 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217203
17204 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0117205 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1617206 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217207 EXPECT_EQ("falafel", response_data);
17208
dcheng48459ac22014-08-26 00:46:4117209 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217210}
17211
17212// Tests that when a SSL connection is established but there's no corresponding
17213// request that needs it, the new socket is closed if the transport socket pool
17214// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117215TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5217216 ClientSocketPoolManager::set_max_sockets_per_group(
17217 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17218 ClientSocketPoolManager::set_max_sockets_per_pool(
17219 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17220
17221 // Set up an ssl request.
17222
17223 HttpRequestInfo ssl_request;
17224 ssl_request.method = "GET";
17225 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1017226 ssl_request.traffic_annotation =
17227 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217228
17229 // No data will be sent on the SSL socket.
17230 StaticSocketDataProvider ssl_data;
17231 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17232
17233 SSLSocketDataProvider ssl(ASYNC, OK);
17234 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17235
17236 // Set up HTTP request.
17237
17238 HttpRequestInfo http_request;
17239 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317240 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017241 http_request.traffic_annotation =
17242 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217243
17244 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317245 MockWrite(
17246 "GET / HTTP/1.1\r\n"
17247 "Host: www.example.org\r\n"
17248 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217249 };
17250 MockRead http_reads[] = {
17251 MockRead("HTTP/1.1 200 OK\r\n"),
17252 MockRead("Content-Length: 7\r\n\r\n"),
17253 MockRead("falafel"),
17254 MockRead(SYNCHRONOUS, OK),
17255 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117256 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217257 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17258
danakj1fd259a02016-04-16 03:17:0917259 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217260
17261 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
17262 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2917263 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5917264 http_stream_factory->PreconnectStreams(1, ssl_request);
Matt Menke9d5e2c92019-02-05 01:42:2317265 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217266
17267 // Start the HTTP request. Pool should stall.
17268 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617269 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017270 ASSERT_EQ(ERR_IO_PENDING,
17271 http_trans.Start(&http_request, http_callback.callback(),
17272 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117273 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217274
17275 // The SSL connection will automatically be closed once the connection is
17276 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0117277 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217278 std::string response_data;
bnc691fda62016-08-12 00:43:1617279 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217280 EXPECT_EQ("falafel", response_data);
17281
dcheng48459ac22014-08-26 00:46:4117282 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217283}
17284
bncd16676a2016-07-20 16:23:0117285TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917286 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217287 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917288 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217289 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417290
17291 HttpRequestInfo request;
17292 request.method = "POST";
17293 request.url = GURL("http://www.foo.com/");
17294 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017295 request.traffic_annotation =
17296 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417297
danakj1fd259a02016-04-16 03:17:0917298 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617299 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417300 // Send headers successfully, but get an error while sending the body.
17301 MockWrite data_writes[] = {
17302 MockWrite("POST / HTTP/1.1\r\n"
17303 "Host: www.foo.com\r\n"
17304 "Connection: keep-alive\r\n"
17305 "Content-Length: 3\r\n\r\n"),
17306 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17307 };
17308
17309 MockRead data_reads[] = {
17310 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17311 MockRead("hello world"),
17312 MockRead(SYNCHRONOUS, OK),
17313 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117314 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417315 session_deps_.socket_factory->AddSocketDataProvider(&data);
17316
17317 TestCompletionCallback callback;
17318
tfarina42834112016-09-22 13:38:2017319 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117320 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417321
17322 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117323 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417324
bnc691fda62016-08-12 00:43:1617325 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217326 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417327
wezca1070932016-05-26 20:30:5217328 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417329 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17330
17331 std::string response_data;
bnc691fda62016-08-12 00:43:1617332 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117333 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417334 EXPECT_EQ("hello world", response_data);
17335}
17336
17337// This test makes sure the retry logic doesn't trigger when reading an error
17338// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0117339TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417340 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0917341 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5417342 MockWrite data_writes[] = {
17343 MockWrite("GET / HTTP/1.1\r\n"
17344 "Host: www.foo.com\r\n"
17345 "Connection: keep-alive\r\n\r\n"),
17346 MockWrite("POST / HTTP/1.1\r\n"
17347 "Host: www.foo.com\r\n"
17348 "Connection: keep-alive\r\n"
17349 "Content-Length: 3\r\n\r\n"),
17350 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17351 };
17352
17353 MockRead data_reads[] = {
17354 MockRead("HTTP/1.1 200 Peachy\r\n"
17355 "Content-Length: 14\r\n\r\n"),
17356 MockRead("first response"),
17357 MockRead("HTTP/1.1 400 Not OK\r\n"
17358 "Content-Length: 15\r\n\r\n"),
17359 MockRead("second response"),
17360 MockRead(SYNCHRONOUS, OK),
17361 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117362 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417363 session_deps_.socket_factory->AddSocketDataProvider(&data);
17364
17365 TestCompletionCallback callback;
17366 HttpRequestInfo request1;
17367 request1.method = "GET";
17368 request1.url = GURL("http://www.foo.com/");
17369 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1017370 request1.traffic_annotation =
17371 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417372
bnc87dcefc2017-05-25 12:47:5817373 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1917374 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017375 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117376 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417377
17378 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117379 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417380
17381 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5217382 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5417383
wezca1070932016-05-26 20:30:5217384 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5417385 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
17386
17387 std::string response_data1;
17388 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0117389 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417390 EXPECT_EQ("first response", response_data1);
17391 // Delete the transaction to release the socket back into the socket pool.
17392 trans1.reset();
17393
danakj1fd259a02016-04-16 03:17:0917394 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217395 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917396 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217397 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417398
17399 HttpRequestInfo request2;
17400 request2.method = "POST";
17401 request2.url = GURL("http://www.foo.com/");
17402 request2.upload_data_stream = &upload_data_stream;
17403 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1017404 request2.traffic_annotation =
17405 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417406
bnc691fda62016-08-12 00:43:1617407 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017408 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417410
17411 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117412 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417413
bnc691fda62016-08-12 00:43:1617414 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5217415 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5417416
wezca1070932016-05-26 20:30:5217417 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5417418 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
17419
17420 std::string response_data2;
bnc691fda62016-08-12 00:43:1617421 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0117422 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417423 EXPECT_EQ("second response", response_data2);
17424}
17425
bncd16676a2016-07-20 16:23:0117426TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417427 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0917428 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217429 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917430 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217431 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417432
17433 HttpRequestInfo request;
17434 request.method = "POST";
17435 request.url = GURL("http://www.foo.com/");
17436 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017437 request.traffic_annotation =
17438 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417439
danakj1fd259a02016-04-16 03:17:0917440 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617441 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417442 // Send headers successfully, but get an error while sending the body.
17443 MockWrite data_writes[] = {
17444 MockWrite("POST / HTTP/1.1\r\n"
17445 "Host: www.foo.com\r\n"
17446 "Connection: keep-alive\r\n"
17447 "Content-Length: 3\r\n\r\n"
17448 "fo"),
17449 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17450 };
17451
17452 MockRead data_reads[] = {
17453 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17454 MockRead("hello world"),
17455 MockRead(SYNCHRONOUS, OK),
17456 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117457 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417458 session_deps_.socket_factory->AddSocketDataProvider(&data);
17459
17460 TestCompletionCallback callback;
17461
tfarina42834112016-09-22 13:38:2017462 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117463 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417464
17465 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117466 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417467
bnc691fda62016-08-12 00:43:1617468 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217469 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417470
wezca1070932016-05-26 20:30:5217471 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417472 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17473
17474 std::string response_data;
bnc691fda62016-08-12 00:43:1617475 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117476 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417477 EXPECT_EQ("hello world", response_data);
17478}
17479
17480// This tests the more common case than the previous test, where headers and
17481// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0117482TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0717483 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5417484
17485 HttpRequestInfo request;
17486 request.method = "POST";
17487 request.url = GURL("http://www.foo.com/");
17488 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017489 request.traffic_annotation =
17490 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417491
danakj1fd259a02016-04-16 03:17:0917492 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617493 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417494 // Send headers successfully, but get an error while sending the body.
17495 MockWrite data_writes[] = {
17496 MockWrite("POST / HTTP/1.1\r\n"
17497 "Host: www.foo.com\r\n"
17498 "Connection: keep-alive\r\n"
17499 "Transfer-Encoding: chunked\r\n\r\n"),
17500 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17501 };
17502
17503 MockRead data_reads[] = {
17504 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17505 MockRead("hello world"),
17506 MockRead(SYNCHRONOUS, OK),
17507 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117508 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417509 session_deps_.socket_factory->AddSocketDataProvider(&data);
17510
17511 TestCompletionCallback callback;
17512
tfarina42834112016-09-22 13:38:2017513 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117514 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417515 // Make sure the headers are sent before adding a chunk. This ensures that
17516 // they can't be merged with the body in a single send. Not currently
17517 // necessary since a chunked body is never merged with headers, but this makes
17518 // the test more future proof.
17519 base::RunLoop().RunUntilIdle();
17520
mmenkecbc2b712014-10-09 20:29:0717521 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5417522
17523 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117524 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417525
bnc691fda62016-08-12 00:43:1617526 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217527 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417528
wezca1070932016-05-26 20:30:5217529 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417530 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17531
17532 std::string response_data;
bnc691fda62016-08-12 00:43:1617533 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117534 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417535 EXPECT_EQ("hello world", response_data);
17536}
17537
bncd16676a2016-07-20 16:23:0117538TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917539 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217540 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917541 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217542 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417543
17544 HttpRequestInfo request;
17545 request.method = "POST";
17546 request.url = GURL("http://www.foo.com/");
17547 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017548 request.traffic_annotation =
17549 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417550
danakj1fd259a02016-04-16 03:17:0917551 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617552 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417553
17554 MockWrite data_writes[] = {
17555 MockWrite("POST / HTTP/1.1\r\n"
17556 "Host: www.foo.com\r\n"
17557 "Connection: keep-alive\r\n"
17558 "Content-Length: 3\r\n\r\n"),
17559 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17560 };
17561
17562 MockRead data_reads[] = {
17563 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17564 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17565 MockRead("hello world"),
17566 MockRead(SYNCHRONOUS, OK),
17567 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117568 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417569 session_deps_.socket_factory->AddSocketDataProvider(&data);
17570
17571 TestCompletionCallback callback;
17572
tfarina42834112016-09-22 13:38:2017573 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117574 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417575
17576 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117577 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417578
bnc691fda62016-08-12 00:43:1617579 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217580 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417581
wezca1070932016-05-26 20:30:5217582 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417583 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17584
17585 std::string response_data;
bnc691fda62016-08-12 00:43:1617586 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117587 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417588 EXPECT_EQ("hello world", response_data);
17589}
17590
bncd16676a2016-07-20 16:23:0117591TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917592 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217593 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917594 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217595 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417596
17597 HttpRequestInfo request;
17598 request.method = "POST";
17599 request.url = GURL("http://www.foo.com/");
17600 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017601 request.traffic_annotation =
17602 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417603
danakj1fd259a02016-04-16 03:17:0917604 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617605 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417606 // Send headers successfully, but get an error while sending the body.
17607 MockWrite data_writes[] = {
17608 MockWrite("POST / HTTP/1.1\r\n"
17609 "Host: www.foo.com\r\n"
17610 "Connection: keep-alive\r\n"
17611 "Content-Length: 3\r\n\r\n"),
17612 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17613 };
17614
17615 MockRead data_reads[] = {
17616 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17617 MockRead("hello world"),
17618 MockRead(SYNCHRONOUS, OK),
17619 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117620 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417621 session_deps_.socket_factory->AddSocketDataProvider(&data);
17622
17623 TestCompletionCallback callback;
17624
tfarina42834112016-09-22 13:38:2017625 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117626 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417627
17628 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117629 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417630}
17631
bncd16676a2016-07-20 16:23:0117632TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417633 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917634 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217635 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917636 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217637 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417638
17639 HttpRequestInfo request;
17640 request.method = "POST";
17641 request.url = GURL("http://www.foo.com/");
17642 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017643 request.traffic_annotation =
17644 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417645
danakj1fd259a02016-04-16 03:17:0917646 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617647 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417648 // Send headers successfully, but get an error while sending the body.
17649 MockWrite data_writes[] = {
17650 MockWrite("POST / HTTP/1.1\r\n"
17651 "Host: www.foo.com\r\n"
17652 "Connection: keep-alive\r\n"
17653 "Content-Length: 3\r\n\r\n"),
17654 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17655 };
17656
17657 MockRead data_reads[] = {
17658 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17659 MockRead("HTTP/1.0 302 Redirect\r\n"),
17660 MockRead("Location: http://somewhere-else.com/\r\n"),
17661 MockRead("Content-Length: 0\r\n\r\n"),
17662 MockRead(SYNCHRONOUS, OK),
17663 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117664 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417665 session_deps_.socket_factory->AddSocketDataProvider(&data);
17666
17667 TestCompletionCallback callback;
17668
tfarina42834112016-09-22 13:38:2017669 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117670 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417671
17672 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117673 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417674}
17675
bncd16676a2016-07-20 16:23:0117676TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917677 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217678 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917679 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217680 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417681
17682 HttpRequestInfo request;
17683 request.method = "POST";
17684 request.url = GURL("http://www.foo.com/");
17685 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017686 request.traffic_annotation =
17687 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417688
danakj1fd259a02016-04-16 03:17:0917689 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617690 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417691 // Send headers successfully, but get an error while sending the body.
17692 MockWrite data_writes[] = {
17693 MockWrite("POST / HTTP/1.1\r\n"
17694 "Host: www.foo.com\r\n"
17695 "Connection: keep-alive\r\n"
17696 "Content-Length: 3\r\n\r\n"),
17697 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17698 };
17699
17700 MockRead data_reads[] = {
17701 MockRead("HTTP 0.9 rocks!"),
17702 MockRead(SYNCHRONOUS, OK),
17703 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117704 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417705 session_deps_.socket_factory->AddSocketDataProvider(&data);
17706
17707 TestCompletionCallback callback;
17708
tfarina42834112016-09-22 13:38:2017709 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117710 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417711
17712 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117713 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417714}
17715
bncd16676a2016-07-20 16:23:0117716TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917717 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217718 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917719 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217720 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417721
17722 HttpRequestInfo request;
17723 request.method = "POST";
17724 request.url = GURL("http://www.foo.com/");
17725 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017726 request.traffic_annotation =
17727 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417728
danakj1fd259a02016-04-16 03:17:0917729 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417731 // Send headers successfully, but get an error while sending the body.
17732 MockWrite data_writes[] = {
17733 MockWrite("POST / HTTP/1.1\r\n"
17734 "Host: www.foo.com\r\n"
17735 "Connection: keep-alive\r\n"
17736 "Content-Length: 3\r\n\r\n"),
17737 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17738 };
17739
17740 MockRead data_reads[] = {
17741 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17742 MockRead(SYNCHRONOUS, OK),
17743 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117744 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417745 session_deps_.socket_factory->AddSocketDataProvider(&data);
17746
17747 TestCompletionCallback callback;
17748
tfarina42834112016-09-22 13:38:2017749 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117750 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417751
17752 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117753 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417754}
17755
Bence Békydca6bd92018-01-30 13:43:0617756#if BUILDFLAG(ENABLE_WEBSOCKETS)
17757
17758namespace {
17759
17760void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17761 headers->SetHeader("Connection", "Upgrade");
17762 headers->SetHeader("Upgrade", "websocket");
17763 headers->SetHeader("Origin", "http://www.example.org");
17764 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617765}
17766
17767} // namespace
17768
17769TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Béky2fcf4fa2018-04-06 20:06:0117770 for (bool secure : {true, false}) {
17771 MockWrite data_writes[] = {
17772 MockWrite("GET / HTTP/1.1\r\n"
17773 "Host: www.example.org\r\n"
17774 "Connection: Upgrade\r\n"
17775 "Upgrade: websocket\r\n"
17776 "Origin: http://www.example.org\r\n"
17777 "Sec-WebSocket-Version: 13\r\n"
17778 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17779 "Sec-WebSocket-Extensions: permessage-deflate; "
17780 "client_max_window_bits\r\n\r\n")};
17781
17782 MockRead data_reads[] = {
17783 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17784 "Upgrade: websocket\r\n"
17785 "Connection: Upgrade\r\n"
17786 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
17787
Ryan Sleevib8d7ea02018-05-07 20:01:0117788 StaticSocketDataProvider data(data_reads, data_writes);
Bence Béky2fcf4fa2018-04-06 20:06:0117789 session_deps_.socket_factory->AddSocketDataProvider(&data);
17790 SSLSocketDataProvider ssl(ASYNC, OK);
17791 if (secure)
17792 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
Bence Békydca6bd92018-01-30 13:43:0617793
17794 HttpRequestInfo request;
17795 request.method = "GET";
Bence Béky2fcf4fa2018-04-06 20:06:0117796 request.url =
17797 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17798 AddWebSocketHeaders(&request.extra_headers);
Ramin Halavatib5e433e2018-02-07 07:41:1017799 request.traffic_annotation =
17800 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617801
Bence Béky2fcf4fa2018-04-06 20:06:0117802 TestWebSocketHandshakeStreamCreateHelper
17803 websocket_handshake_stream_create_helper;
Bence Béky8d1c6052018-02-07 12:48:1517804
Bence Béky2fcf4fa2018-04-06 20:06:0117805 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Bence Békydca6bd92018-01-30 13:43:0617806 HttpNetworkTransaction trans(LOW, session.get());
17807 trans.SetWebSocketHandshakeStreamCreateHelper(
Bence Béky2fcf4fa2018-04-06 20:06:0117808 &websocket_handshake_stream_create_helper);
Bence Békydca6bd92018-01-30 13:43:0617809
17810 TestCompletionCallback callback;
Bence Béky2fcf4fa2018-04-06 20:06:0117811 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17812 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Bence Békydca6bd92018-01-30 13:43:0617813
Bence Béky2fcf4fa2018-04-06 20:06:0117814 const HttpStreamRequest* stream_request = trans.stream_request_.get();
17815 ASSERT_TRUE(stream_request);
17816 EXPECT_EQ(&websocket_handshake_stream_create_helper,
17817 stream_request->websocket_handshake_stream_create_helper());
17818
17819 rv = callback.WaitForResult();
17820 EXPECT_THAT(rv, IsOk());
17821
17822 EXPECT_TRUE(data.AllReadDataConsumed());
17823 EXPECT_TRUE(data.AllWriteDataConsumed());
Bence Békydca6bd92018-01-30 13:43:0617824 }
17825}
17826
Adam Rice425cf122015-01-19 06:18:2417827// Verify that proxy headers are not sent to the destination server when
17828// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117829TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417830 HttpRequestInfo request;
17831 request.method = "GET";
bncce36dca22015-04-21 22:11:2317832 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017833 request.traffic_annotation =
17834 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417835 AddWebSocketHeaders(&request.extra_headers);
17836
17837 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917838 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917839 ProxyResolutionService::CreateFixedFromPacResult(
17840 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417841
danakj1fd259a02016-04-16 03:17:0917842 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417843
17844 // Since a proxy is configured, try to establish a tunnel.
17845 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717846 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17847 "Host: www.example.org:443\r\n"
17848 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417849
17850 // After calling trans->RestartWithAuth(), this is the request we should
17851 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717852 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17853 "Host: www.example.org:443\r\n"
17854 "Proxy-Connection: keep-alive\r\n"
17855 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417856
rsleevidb16bb02015-11-12 23:47:1717857 MockWrite("GET / HTTP/1.1\r\n"
17858 "Host: www.example.org\r\n"
17859 "Connection: Upgrade\r\n"
17860 "Upgrade: websocket\r\n"
17861 "Origin: http://www.example.org\r\n"
17862 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517863 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17864 "Sec-WebSocket-Extensions: permessage-deflate; "
17865 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417866
17867 // The proxy responds to the connect with a 407, using a persistent
17868 // connection.
17869 MockRead data_reads[] = {
17870 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517871 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17872 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17873 "Content-Length: 0\r\n"
17874 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417875
17876 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17877
Bence Béky8d1c6052018-02-07 12:48:1517878 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17879 "Upgrade: websocket\r\n"
17880 "Connection: Upgrade\r\n"
17881 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417882
Ryan Sleevib8d7ea02018-05-07 20:01:0117883 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417884 session_deps_.socket_factory->AddSocketDataProvider(&data);
17885 SSLSocketDataProvider ssl(ASYNC, OK);
17886 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17887
Bence Béky8d1c6052018-02-07 12:48:1517888 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17889
bnc87dcefc2017-05-25 12:47:5817890 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917891 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417892 trans->SetWebSocketHandshakeStreamCreateHelper(
17893 &websocket_stream_create_helper);
17894
17895 {
17896 TestCompletionCallback callback;
17897
tfarina42834112016-09-22 13:38:2017898 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117899 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417900
17901 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117902 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417903 }
17904
17905 const HttpResponseInfo* response = trans->GetResponseInfo();
17906 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217907 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417908 EXPECT_EQ(407, response->headers->response_code());
17909
17910 {
17911 TestCompletionCallback callback;
17912
17913 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17914 callback.callback());
robpercival214763f2016-07-01 23:27:0117915 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417916
17917 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117918 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417919 }
17920
17921 response = trans->GetResponseInfo();
17922 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217923 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417924
17925 EXPECT_EQ(101, response->headers->response_code());
17926
17927 trans.reset();
17928 session->CloseAllConnections();
17929}
17930
17931// Verify that proxy headers are not sent to the destination server when
17932// establishing a tunnel for an insecure WebSocket connection.
17933// This requires the authentication info to be injected into the auth cache
17934// due to crbug.com/395064
17935// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117936TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417937 HttpRequestInfo request;
17938 request.method = "GET";
bncce36dca22015-04-21 22:11:2317939 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017940 request.traffic_annotation =
17941 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417942 AddWebSocketHeaders(&request.extra_headers);
17943
17944 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917945 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917946 ProxyResolutionService::CreateFixedFromPacResult(
17947 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417948
danakj1fd259a02016-04-16 03:17:0917949 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417950
17951 MockWrite data_writes[] = {
17952 // Try to establish a tunnel for the WebSocket connection, with
17953 // credentials. Because WebSockets have a separate set of socket pools,
17954 // they cannot and will not use the same TCP/IP connection as the
17955 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517956 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17957 "Host: www.example.org:80\r\n"
17958 "Proxy-Connection: keep-alive\r\n"
17959 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417960
Bence Béky8d1c6052018-02-07 12:48:1517961 MockWrite("GET / HTTP/1.1\r\n"
17962 "Host: www.example.org\r\n"
17963 "Connection: Upgrade\r\n"
17964 "Upgrade: websocket\r\n"
17965 "Origin: http://www.example.org\r\n"
17966 "Sec-WebSocket-Version: 13\r\n"
17967 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17968 "Sec-WebSocket-Extensions: permessage-deflate; "
17969 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417970
17971 MockRead data_reads[] = {
17972 // HTTP CONNECT with credentials.
17973 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17974
17975 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517976 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17977 "Upgrade: websocket\r\n"
17978 "Connection: Upgrade\r\n"
17979 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417980
Ryan Sleevib8d7ea02018-05-07 20:01:0117981 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417982 session_deps_.socket_factory->AddSocketDataProvider(&data);
17983
17984 session->http_auth_cache()->Add(
17985 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17986 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17987
Bence Béky8d1c6052018-02-07 12:48:1517988 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17989
bnc87dcefc2017-05-25 12:47:5817990 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917991 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417992 trans->SetWebSocketHandshakeStreamCreateHelper(
17993 &websocket_stream_create_helper);
17994
17995 TestCompletionCallback callback;
17996
tfarina42834112016-09-22 13:38:2017997 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117998 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417999
18000 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0118001 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2418002
18003 const HttpResponseInfo* response = trans->GetResponseInfo();
18004 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5218005 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2418006
18007 EXPECT_EQ(101, response->headers->response_code());
18008
18009 trans.reset();
18010 session->CloseAllConnections();
18011}
18012
Bence Békydca6bd92018-01-30 13:43:0618013#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
18014
bncd16676a2016-07-20 16:23:0118015TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0918016 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2218017 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1918018 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2218019 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2218020
18021 HttpRequestInfo request;
18022 request.method = "POST";
18023 request.url = GURL("http://www.foo.com/");
18024 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1018025 request.traffic_annotation =
18026 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218027
danakj1fd259a02016-04-16 03:17:0918028 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618029 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218030 MockWrite data_writes[] = {
18031 MockWrite("POST / HTTP/1.1\r\n"
18032 "Host: www.foo.com\r\n"
18033 "Connection: keep-alive\r\n"
18034 "Content-Length: 3\r\n\r\n"),
18035 MockWrite("foo"),
18036 };
18037
18038 MockRead data_reads[] = {
18039 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18040 MockRead(SYNCHRONOUS, OK),
18041 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118042 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218043 session_deps_.socket_factory->AddSocketDataProvider(&data);
18044
18045 TestCompletionCallback callback;
18046
18047 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018048 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0118049 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218050
18051 std::string response_data;
bnc691fda62016-08-12 00:43:1618052 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218053
Ryan Sleevib8d7ea02018-05-07 20:01:0118054 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18055 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218056}
18057
bncd16676a2016-07-20 16:23:0118058TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0918059 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2218060 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1918061 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2218062 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2218063
18064 HttpRequestInfo request;
18065 request.method = "POST";
18066 request.url = GURL("http://www.foo.com/");
18067 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1018068 request.traffic_annotation =
18069 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218070
danakj1fd259a02016-04-16 03:17:0918071 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618072 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218073 MockWrite data_writes[] = {
18074 MockWrite("POST / HTTP/1.1\r\n"
18075 "Host: www.foo.com\r\n"
18076 "Connection: keep-alive\r\n"
18077 "Content-Length: 3\r\n\r\n"),
18078 MockWrite("foo"),
18079 };
18080
18081 MockRead data_reads[] = {
18082 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
18083 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18084 MockRead(SYNCHRONOUS, OK),
18085 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118086 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218087 session_deps_.socket_factory->AddSocketDataProvider(&data);
18088
18089 TestCompletionCallback callback;
18090
18091 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018092 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0118093 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218094
18095 std::string response_data;
bnc691fda62016-08-12 00:43:1618096 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218097
Ryan Sleevib8d7ea02018-05-07 20:01:0118098 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18099 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218100}
18101
bncd16676a2016-07-20 16:23:0118102TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2218103 ChunkedUploadDataStream upload_data_stream(0);
18104
18105 HttpRequestInfo request;
18106 request.method = "POST";
18107 request.url = GURL("http://www.foo.com/");
18108 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1018109 request.traffic_annotation =
18110 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218111
danakj1fd259a02016-04-16 03:17:0918112 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618113 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218114 // Send headers successfully, but get an error while sending the body.
18115 MockWrite data_writes[] = {
18116 MockWrite("POST / HTTP/1.1\r\n"
18117 "Host: www.foo.com\r\n"
18118 "Connection: keep-alive\r\n"
18119 "Transfer-Encoding: chunked\r\n\r\n"),
18120 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
18121 };
18122
18123 MockRead data_reads[] = {
18124 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18125 MockRead(SYNCHRONOUS, OK),
18126 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118127 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218128 session_deps_.socket_factory->AddSocketDataProvider(&data);
18129
18130 TestCompletionCallback callback;
18131
18132 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018133 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2218134
18135 base::RunLoop().RunUntilIdle();
18136 upload_data_stream.AppendData("f", 1, false);
18137
18138 base::RunLoop().RunUntilIdle();
18139 upload_data_stream.AppendData("oo", 2, true);
18140
robpercival214763f2016-07-01 23:27:0118141 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218142
18143 std::string response_data;
bnc691fda62016-08-12 00:43:1618144 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218145
Ryan Sleevib8d7ea02018-05-07 20:01:0118146 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18147 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218148}
18149
eustasc7d27da2017-04-06 10:33:2018150void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
18151 const std::string& accept_encoding,
18152 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0318153 const std::string& location,
eustasc7d27da2017-04-06 10:33:2018154 bool should_match) {
18155 HttpRequestInfo request;
18156 request.method = "GET";
18157 request.url = GURL("http://www.foo.com/");
18158 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
18159 accept_encoding);
Ramin Halavatib5e433e2018-02-07 07:41:1018160 request.traffic_annotation =
18161 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2018162
18163 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
18164 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18165 // Send headers successfully, but get an error while sending the body.
18166 MockWrite data_writes[] = {
18167 MockWrite("GET / HTTP/1.1\r\n"
18168 "Host: www.foo.com\r\n"
18169 "Connection: keep-alive\r\n"
18170 "Accept-Encoding: "),
18171 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
18172 };
18173
sky50576f32017-05-01 19:28:0318174 std::string response_code = "200 OK";
18175 std::string extra;
18176 if (!location.empty()) {
18177 response_code = "301 Redirect\r\nLocation: ";
18178 response_code.append(location);
18179 }
18180
eustasc7d27da2017-04-06 10:33:2018181 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0318182 MockRead("HTTP/1.0 "),
18183 MockRead(response_code.data()),
18184 MockRead("\r\nContent-Encoding: "),
18185 MockRead(content_encoding.data()),
18186 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2018187 MockRead(SYNCHRONOUS, OK),
18188 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118189 StaticSocketDataProvider data(data_reads, data_writes);
eustasc7d27da2017-04-06 10:33:2018190 session_deps->socket_factory->AddSocketDataProvider(&data);
18191
18192 TestCompletionCallback callback;
18193
18194 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18195 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18196
18197 rv = callback.WaitForResult();
18198 if (should_match) {
18199 EXPECT_THAT(rv, IsOk());
18200 } else {
18201 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
18202 }
18203}
18204
18205TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0318206 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2018207}
18208
18209TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0318210 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
18211 true);
eustasc7d27da2017-04-06 10:33:2018212}
18213
18214TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
18215 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0318216 "", false);
18217}
18218
18219TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
18220 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
18221 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2018222}
18223
xunjieli96f2a402017-06-05 17:24:2718224TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
18225 ProxyConfig proxy_config;
18226 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18227 proxy_config.set_pac_mandatory(true);
18228 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918229 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918230 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18231 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0418232 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2718233
18234 HttpRequestInfo request;
18235 request.method = "GET";
18236 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018237 request.traffic_annotation =
18238 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718239
18240 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18241 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18242
18243 TestCompletionCallback callback;
18244
18245 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18246 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18247 EXPECT_THAT(callback.WaitForResult(),
18248 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18249}
18250
18251TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
18252 ProxyConfig proxy_config;
18253 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18254 proxy_config.set_pac_mandatory(true);
18255 MockAsyncProxyResolverFactory* proxy_resolver_factory =
18256 new MockAsyncProxyResolverFactory(false);
18257 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918258 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918259 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18260 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5918261 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2718262 HttpRequestInfo request;
18263 request.method = "GET";
18264 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018265 request.traffic_annotation =
18266 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718267
18268 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18269 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18270
18271 TestCompletionCallback callback;
18272 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18273 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18274
18275 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
18276 ERR_FAILED, &resolver);
18277 EXPECT_THAT(callback.WaitForResult(),
18278 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18279}
18280
18281TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5918282 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4918283 ProxyResolutionService::CreateFixedFromPacResult(
18284 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718285 session_deps_.enable_quic = false;
18286 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18287
18288 HttpRequestInfo request;
18289 request.method = "GET";
18290 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1018291 request.traffic_annotation =
18292 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718293
18294 TestCompletionCallback callback;
18295 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18296 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18297 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18298
18299 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18300}
18301
Douglas Creager3cb042052018-11-06 23:08:5218302//-----------------------------------------------------------------------------
Douglas Creager134b52e2018-11-09 18:00:1418303// Reporting tests
18304
18305#if BUILDFLAG(ENABLE_REPORTING)
18306class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest {
18307 protected:
18308 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618309 HttpNetworkTransactionTest::SetUp();
Douglas Creager134b52e2018-11-09 18:00:1418310 auto test_reporting_context = std::make_unique<TestReportingContext>(
18311 &clock_, &tick_clock_, ReportingPolicy());
18312 test_reporting_context_ = test_reporting_context.get();
18313 session_deps_.reporting_service =
18314 ReportingService::CreateForTesting(std::move(test_reporting_context));
18315 }
18316
18317 TestReportingContext* reporting_context() const {
18318 return test_reporting_context_;
18319 }
18320
18321 void clear_reporting_service() {
18322 session_deps_.reporting_service.reset();
18323 test_reporting_context_ = nullptr;
18324 }
18325
18326 // Makes an HTTPS request that should install a valid Reporting policy.
Lily Chenfec60d92019-01-24 01:16:4218327 void RequestPolicy(CertStatus cert_status = 0) {
18328 HttpRequestInfo request;
18329 request.method = "GET";
18330 request.url = GURL(url_);
18331 request.traffic_annotation =
18332 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18333
Lily Chend3930e72019-03-01 19:31:1118334 MockWrite data_writes[] = {
18335 MockWrite("GET / HTTP/1.1\r\n"
18336 "Host: www.example.org\r\n"
18337 "Connection: keep-alive\r\n\r\n"),
18338 };
Douglas Creager134b52e2018-11-09 18:00:1418339 MockRead data_reads[] = {
18340 MockRead("HTTP/1.0 200 OK\r\n"),
18341 MockRead("Report-To: {\"group\": \"nel\", \"max_age\": 86400, "
18342 "\"endpoints\": [{\"url\": "
18343 "\"https://www.example.org/upload/\"}]}\r\n"),
18344 MockRead("\r\n"),
18345 MockRead("hello world"),
18346 MockRead(SYNCHRONOUS, OK),
18347 };
Douglas Creager134b52e2018-11-09 18:00:1418348
Lily Chenfec60d92019-01-24 01:16:4218349 StaticSocketDataProvider reads(data_reads, data_writes);
18350 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager134b52e2018-11-09 18:00:1418351
18352 SSLSocketDataProvider ssl(ASYNC, OK);
18353 if (request.url.SchemeIsCryptographic()) {
18354 ssl.ssl_info.cert =
18355 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18356 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218357 ssl.ssl_info.cert_status = cert_status;
Douglas Creager134b52e2018-11-09 18:00:1418358 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18359 }
18360
Douglas Creager134b52e2018-11-09 18:00:1418361 TestCompletionCallback callback;
18362 auto session = CreateSession(&session_deps_);
18363 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18364 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
Lily Chenfec60d92019-01-24 01:16:4218365 EXPECT_THAT(callback.GetResult(rv), IsOk());
Douglas Creager134b52e2018-11-09 18:00:1418366 }
18367
18368 protected:
18369 std::string url_ = "https://www.example.org/";
Douglas Creager134b52e2018-11-09 18:00:1418370
18371 private:
18372 TestReportingContext* test_reporting_context_;
18373};
18374
18375TEST_F(HttpNetworkTransactionReportingTest,
18376 DontProcessReportToHeaderNoService) {
18377 base::HistogramTester histograms;
18378 clear_reporting_service();
18379 RequestPolicy();
18380 histograms.ExpectBucketCount(
18381 ReportingHeaderParser::kHeaderOutcomeHistogram,
18382 ReportingHeaderParser::HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE, 1);
18383}
18384
18385TEST_F(HttpNetworkTransactionReportingTest, DontProcessReportToHeaderHttp) {
18386 base::HistogramTester histograms;
18387 url_ = "http://www.example.org/";
18388 RequestPolicy();
18389 histograms.ExpectBucketCount(
18390 ReportingHeaderParser::kHeaderOutcomeHistogram,
18391 ReportingHeaderParser::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18392}
18393
18394TEST_F(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
18395 RequestPolicy();
18396 std::vector<const ReportingClient*> clients;
18397 reporting_context()->cache()->GetClients(&clients);
18398 ASSERT_EQ(1u, clients.size());
18399 const auto* client = clients[0];
18400 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18401 client->origin);
18402 EXPECT_EQ(GURL("https://www.example.org/upload/"), client->endpoint);
18403 EXPECT_EQ("nel", client->group);
18404}
18405
18406TEST_F(HttpNetworkTransactionReportingTest,
18407 DontProcessReportToHeaderInvalidHttps) {
18408 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218409 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18410 RequestPolicy(cert_status);
Douglas Creager134b52e2018-11-09 18:00:1418411 histograms.ExpectBucketCount(
18412 ReportingHeaderParser::kHeaderOutcomeHistogram,
18413 ReportingHeaderParser::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR, 1);
18414}
18415#endif // BUILDFLAG(ENABLE_REPORTING)
18416
18417//-----------------------------------------------------------------------------
Douglas Creager3cb042052018-11-06 23:08:5218418// Network Error Logging tests
18419
18420#if BUILDFLAG(ENABLE_REPORTING)
Lily Chenfec60d92019-01-24 01:16:4218421namespace {
18422
18423const char kUserAgent[] = "Mozilla/1.0";
18424const char kReferrer[] = "https://www.referrer.org/";
18425
18426} // namespace
18427
Douglas Creager3cb042052018-11-06 23:08:5218428class HttpNetworkTransactionNetworkErrorLoggingTest
18429 : public HttpNetworkTransactionTest {
18430 protected:
18431 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618432 HttpNetworkTransactionTest::SetUp();
Douglas Creager3cb042052018-11-06 23:08:5218433 auto network_error_logging_service =
18434 std::make_unique<TestNetworkErrorLoggingService>();
18435 test_network_error_logging_service_ = network_error_logging_service.get();
18436 session_deps_.network_error_logging_service =
18437 std::move(network_error_logging_service);
Lily Chenfec60d92019-01-24 01:16:4218438
18439 extra_headers_.SetHeader("User-Agent", kUserAgent);
18440 extra_headers_.SetHeader("Referer", kReferrer);
18441
18442 request_.method = "GET";
18443 request_.url = GURL(url_);
18444 request_.extra_headers = extra_headers_;
18445 request_.reporting_upload_depth = reporting_upload_depth_;
18446 request_.traffic_annotation =
18447 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Douglas Creager3cb042052018-11-06 23:08:5218448 }
18449
18450 TestNetworkErrorLoggingService* network_error_logging_service() const {
18451 return test_network_error_logging_service_;
18452 }
18453
18454 void clear_network_error_logging_service() {
18455 session_deps_.network_error_logging_service.reset();
18456 test_network_error_logging_service_ = nullptr;
18457 }
18458
18459 // Makes an HTTPS request that should install a valid NEL policy.
Lily Chenfec60d92019-01-24 01:16:4218460 void RequestPolicy(CertStatus cert_status = 0) {
Douglas Creageref5eecdc2018-11-09 20:50:3618461 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318462 MockWrite data_writes[] = {
18463 MockWrite("GET / HTTP/1.1\r\n"
18464 "Host: www.example.org\r\n"
18465 "Connection: keep-alive\r\n"),
18466 MockWrite(ASYNC, extra_header_string.data(),
18467 extra_header_string.size()),
18468 };
Lily Chend3930e72019-03-01 19:31:1118469 MockRead data_reads[] = {
18470 MockRead("HTTP/1.0 200 OK\r\n"),
18471 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18472 MockRead("\r\n"),
18473 MockRead("hello world"),
18474 MockRead(SYNCHRONOUS, OK),
18475 };
Douglas Creager3cb042052018-11-06 23:08:5218476
Lily Chenfec60d92019-01-24 01:16:4218477 StaticSocketDataProvider reads(data_reads, data_writes);
18478 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager3cb042052018-11-06 23:08:5218479
18480 SSLSocketDataProvider ssl(ASYNC, OK);
Lily Chenfec60d92019-01-24 01:16:4218481 if (request_.url.SchemeIsCryptographic()) {
Douglas Creager3cb042052018-11-06 23:08:5218482 ssl.ssl_info.cert =
18483 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18484 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218485 ssl.ssl_info.cert_status = cert_status;
Douglas Creager3cb042052018-11-06 23:08:5218486 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18487 }
18488
Douglas Creager3cb042052018-11-06 23:08:5218489 TestCompletionCallback callback;
18490 auto session = CreateSession(&session_deps_);
18491 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
Lily Chenfec60d92019-01-24 01:16:4218492 int rv = trans.Start(&request_, callback.callback(), NetLogWithSource());
18493 EXPECT_THAT(callback.GetResult(rv), IsOk());
18494
18495 std::string response_data;
18496 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
18497 EXPECT_EQ("hello world", response_data);
18498 }
18499
18500 void CheckReport(size_t index,
18501 int status_code,
18502 int error_type,
18503 IPAddress server_ip = IPAddress::IPv4Localhost()) {
18504 ASSERT_LT(index, network_error_logging_service()->errors().size());
18505
18506 const NetworkErrorLoggingService::RequestDetails& error =
18507 network_error_logging_service()->errors()[index];
18508 EXPECT_EQ(url_, error.uri);
18509 EXPECT_EQ(kReferrer, error.referrer);
18510 EXPECT_EQ(kUserAgent, error.user_agent);
18511 EXPECT_EQ(server_ip, error.server_ip);
18512 EXPECT_EQ("http/1.1", error.protocol);
18513 EXPECT_EQ("GET", error.method);
18514 EXPECT_EQ(status_code, error.status_code);
18515 EXPECT_EQ(error_type, error.type);
18516 EXPECT_EQ(0, error.reporting_upload_depth);
Douglas Creager3cb042052018-11-06 23:08:5218517 }
18518
18519 protected:
18520 std::string url_ = "https://www.example.org/";
18521 CertStatus cert_status_ = 0;
Lily Chenfec60d92019-01-24 01:16:4218522 HttpRequestInfo request_;
Douglas Creageref5eecdc2018-11-09 20:50:3618523 HttpRequestHeaders extra_headers_;
18524 int reporting_upload_depth_ = 0;
Douglas Creager3cb042052018-11-06 23:08:5218525
18526 private:
18527 TestNetworkErrorLoggingService* test_network_error_logging_service_;
18528};
18529
18530TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18531 DontProcessNelHeaderNoService) {
18532 base::HistogramTester histograms;
18533 clear_network_error_logging_service();
18534 RequestPolicy();
18535 histograms.ExpectBucketCount(
18536 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18537 NetworkErrorLoggingService::HeaderOutcome::
18538 DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE,
18539 1);
18540}
18541
18542TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18543 DontProcessNelHeaderHttp) {
18544 base::HistogramTester histograms;
18545 url_ = "http://www.example.org/";
Lily Chenfec60d92019-01-24 01:16:4218546 request_.url = GURL(url_);
Douglas Creager3cb042052018-11-06 23:08:5218547 RequestPolicy();
18548 histograms.ExpectBucketCount(
18549 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18550 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18551}
18552
Lily Chen90ae93cc2019-02-14 01:15:3918553// Don't set NEL policies received on a proxied connection.
18554TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18555 DontProcessNelHeaderProxy) {
18556 session_deps_.proxy_resolution_service =
18557 ProxyResolutionService::CreateFixedFromPacResult(
18558 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
18559 BoundTestNetLog log;
18560 session_deps_.net_log = log.bound().net_log();
18561 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18562
18563 HttpRequestInfo request;
18564 request.method = "GET";
18565 request.url = GURL("https://www.example.org/");
18566 request.traffic_annotation =
18567 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18568
18569 // Since we have proxy, should try to establish tunnel.
18570 MockWrite data_writes1[] = {
18571 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
18572 "Host: www.example.org:443\r\n"
18573 "Proxy-Connection: keep-alive\r\n\r\n"),
18574
18575 MockWrite("GET / HTTP/1.1\r\n"
18576 "Host: www.example.org\r\n"
18577 "Connection: keep-alive\r\n\r\n"),
18578 };
18579
18580 MockRead data_reads1[] = {
18581 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
18582
18583 MockRead("HTTP/1.1 200 OK\r\n"),
18584 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18585 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18586 MockRead("Content-Length: 100\r\n\r\n"),
18587 MockRead(SYNCHRONOUS, OK),
18588 };
18589
18590 StaticSocketDataProvider data1(data_reads1, data_writes1);
18591 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18592 SSLSocketDataProvider ssl(ASYNC, OK);
18593 ssl.ssl_info.cert =
18594 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18595 ASSERT_TRUE(ssl.ssl_info.cert);
18596 ssl.ssl_info.cert_status = 0;
18597 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18598
18599 TestCompletionCallback callback1;
18600 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18601
18602 int rv = trans.Start(&request, callback1.callback(), log.bound());
18603 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18604
18605 rv = callback1.WaitForResult();
18606 EXPECT_THAT(rv, IsOk());
18607
18608 const HttpResponseInfo* response = trans.GetResponseInfo();
18609 ASSERT_TRUE(response);
18610 EXPECT_EQ(200, response->headers->response_code());
18611 EXPECT_TRUE(response->was_fetched_via_proxy);
18612
18613 // No NEL header was set.
18614 EXPECT_EQ(0u, network_error_logging_service()->headers().size());
18615}
18616
Douglas Creager3cb042052018-11-06 23:08:5218617TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) {
18618 RequestPolicy();
18619 ASSERT_EQ(1u, network_error_logging_service()->headers().size());
18620 const auto& header = network_error_logging_service()->headers()[0];
18621 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18622 header.origin);
18623 EXPECT_EQ(IPAddress::IPv4Localhost(), header.received_ip_address);
18624 EXPECT_EQ("{\"report_to\": \"nel\", \"max_age\": 86400}", header.value);
18625}
18626
18627TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18628 DontProcessNelHeaderInvalidHttps) {
18629 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218630 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18631 RequestPolicy(cert_status);
Douglas Creager3cb042052018-11-06 23:08:5218632 histograms.ExpectBucketCount(
18633 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18634 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR,
18635 1);
18636}
Douglas Creageref5eecdc2018-11-09 20:50:3618637
Lily Chenfec60d92019-01-24 01:16:4218638TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportSuccess) {
Douglas Creageref5eecdc2018-11-09 20:50:3618639 RequestPolicy();
18640 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4218641 CheckReport(0 /* index */, 200 /* status_code */, OK);
18642}
18643
18644TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18645 CreateReportErrorAfterStart) {
18646 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18647 auto trans =
18648 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18649
18650 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
18651 StaticSocketDataProvider data;
18652 data.set_connect_data(mock_connect);
18653 session_deps_.socket_factory->AddSocketDataProvider(&data);
18654
18655 TestCompletionCallback callback;
18656
18657 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18658 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18659
18660 trans.reset();
18661
18662 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18663 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18664 IPAddress() /* server_ip */);
18665}
18666
18667// Same as above except the error is ASYNC
18668TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18669 CreateReportErrorAfterStartAsync) {
18670 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18671 auto trans =
18672 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18673
18674 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
18675 StaticSocketDataProvider data;
18676 data.set_connect_data(mock_connect);
18677 session_deps_.socket_factory->AddSocketDataProvider(&data);
18678
18679 TestCompletionCallback callback;
18680
18681 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18682 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18683
18684 trans.reset();
18685
18686 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18687 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18688 IPAddress() /* server_ip */);
18689}
18690
18691TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18692 CreateReportReadBodyError) {
18693 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318694 MockWrite data_writes[] = {
18695 MockWrite("GET / HTTP/1.1\r\n"
18696 "Host: www.example.org\r\n"
18697 "Connection: keep-alive\r\n"),
18698 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18699 };
Lily Chend3930e72019-03-01 19:31:1118700 MockRead data_reads[] = {
18701 MockRead("HTTP/1.0 200 OK\r\n"),
18702 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18703 MockRead("hello world"),
18704 MockRead(SYNCHRONOUS, OK),
18705 };
Lily Chenfec60d92019-01-24 01:16:4218706
18707 StaticSocketDataProvider reads(data_reads, data_writes);
18708 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18709
18710 SSLSocketDataProvider ssl(ASYNC, OK);
18711 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18712
18713 // Log start time
18714 base::TimeTicks start_time = base::TimeTicks::Now();
18715
18716 TestCompletionCallback callback;
18717 auto session = CreateSession(&session_deps_);
18718 auto trans =
18719 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18720 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18721 EXPECT_THAT(callback.GetResult(rv), IsOk());
18722
18723 const HttpResponseInfo* response = trans->GetResponseInfo();
18724 ASSERT_TRUE(response);
18725
18726 EXPECT_TRUE(response->headers);
18727 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18728
18729 std::string response_data;
18730 rv = ReadTransaction(trans.get(), &response_data);
18731 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18732
18733 trans.reset();
18734
18735 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18736
18737 CheckReport(0 /* index */, 200 /* status_code */,
18738 ERR_CONTENT_LENGTH_MISMATCH);
18739 const NetworkErrorLoggingService::RequestDetails& error =
18740 network_error_logging_service()->errors()[0];
18741 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18742}
18743
18744// Same as above except the final read is ASYNC.
18745TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18746 CreateReportReadBodyErrorAsync) {
18747 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318748 MockWrite data_writes[] = {
18749 MockWrite("GET / HTTP/1.1\r\n"
18750 "Host: www.example.org\r\n"
18751 "Connection: keep-alive\r\n"),
18752 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18753 };
Lily Chend3930e72019-03-01 19:31:1118754 MockRead data_reads[] = {
18755 MockRead("HTTP/1.0 200 OK\r\n"),
18756 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18757 MockRead("hello world"),
18758 MockRead(ASYNC, OK),
18759 };
Lily Chenfec60d92019-01-24 01:16:4218760
18761 StaticSocketDataProvider reads(data_reads, data_writes);
18762 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18763
18764 SSLSocketDataProvider ssl(ASYNC, OK);
18765 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18766
18767 // Log start time
18768 base::TimeTicks start_time = base::TimeTicks::Now();
18769
18770 TestCompletionCallback callback;
18771 auto session = CreateSession(&session_deps_);
18772 auto trans =
18773 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18774 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18775 EXPECT_THAT(callback.GetResult(rv), IsOk());
18776
18777 const HttpResponseInfo* response = trans->GetResponseInfo();
18778 ASSERT_TRUE(response);
18779
18780 EXPECT_TRUE(response->headers);
18781 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18782
18783 std::string response_data;
18784 rv = ReadTransaction(trans.get(), &response_data);
18785 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18786
18787 trans.reset();
18788
18789 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18790
18791 CheckReport(0 /* index */, 200 /* status_code */,
18792 ERR_CONTENT_LENGTH_MISMATCH);
18793 const NetworkErrorLoggingService::RequestDetails& error =
18794 network_error_logging_service()->errors()[0];
18795 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18796}
18797
18798TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18799 CreateReportRestartWithAuth) {
18800 std::string extra_header_string = extra_headers_.ToString();
18801 static const base::TimeDelta kSleepDuration =
18802 base::TimeDelta::FromMilliseconds(10);
18803
18804 MockWrite data_writes1[] = {
18805 MockWrite("GET / HTTP/1.1\r\n"
18806 "Host: www.example.org\r\n"
18807 "Connection: keep-alive\r\n"),
18808 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18809 };
18810
18811 MockRead data_reads1[] = {
18812 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18813 // Give a couple authenticate options (only the middle one is actually
18814 // supported).
18815 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18816 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18817 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18818 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18819 // Large content-length -- won't matter, as connection will be reset.
18820 MockRead("Content-Length: 10000\r\n\r\n"),
18821 MockRead(SYNCHRONOUS, ERR_FAILED),
18822 };
18823
18824 // After calling trans->RestartWithAuth(), this is the request we should
18825 // be issuing -- the final header line contains the credentials.
18826 MockWrite data_writes2[] = {
18827 MockWrite("GET / HTTP/1.1\r\n"
18828 "Host: www.example.org\r\n"
18829 "Connection: keep-alive\r\n"
18830 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18831 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18832 };
18833
18834 // Lastly, the server responds with the actual content.
18835 MockRead data_reads2[] = {
18836 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18837 MockRead("hello world"),
18838 MockRead(SYNCHRONOUS, OK),
18839 };
18840
18841 StaticSocketDataProvider data1(data_reads1, data_writes1);
18842 StaticSocketDataProvider data2(data_reads2, data_writes2);
18843 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18844 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18845
18846 SSLSocketDataProvider ssl1(ASYNC, OK);
18847 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18848 SSLSocketDataProvider ssl2(ASYNC, OK);
18849 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18850
18851 base::TimeTicks start_time = base::TimeTicks::Now();
18852 base::TimeTicks restart_time;
18853
18854 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18855 auto trans =
18856 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18857
18858 TestCompletionCallback callback1;
18859
18860 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18861 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18862
18863 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18864
18865 TestCompletionCallback callback2;
18866
18867 // Wait 10 ms then restart with auth
18868 FastForwardBy(kSleepDuration);
18869 restart_time = base::TimeTicks::Now();
18870 rv =
18871 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18872 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18873
18874 std::string response_data;
18875 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18876 EXPECT_EQ("hello world", response_data);
18877
18878 trans.reset();
18879
18880 // One 401 report for the auth challenge, then a 200 report for the successful
18881 // retry. Note that we don't report the error draining the body, as the first
18882 // request already generated a report for the auth challenge.
18883 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18884
18885 // Check error report contents
18886 CheckReport(0 /* index */, 401 /* status_code */, OK);
18887 CheckReport(1 /* index */, 200 /* status_code */, OK);
18888
18889 const NetworkErrorLoggingService::RequestDetails& error1 =
18890 network_error_logging_service()->errors()[0];
18891 const NetworkErrorLoggingService::RequestDetails& error2 =
18892 network_error_logging_service()->errors()[1];
18893
18894 // Sanity-check elapsed time values
18895 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18896 // Check that the start time is refreshed when restarting with auth.
18897 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18898}
18899
18900// Same as above, except draining the body before restarting fails
18901// asynchronously.
18902TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18903 CreateReportRestartWithAuthAsync) {
18904 std::string extra_header_string = extra_headers_.ToString();
18905 static const base::TimeDelta kSleepDuration =
18906 base::TimeDelta::FromMilliseconds(10);
18907
18908 MockWrite data_writes1[] = {
18909 MockWrite("GET / HTTP/1.1\r\n"
18910 "Host: www.example.org\r\n"
18911 "Connection: keep-alive\r\n"),
18912 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18913 };
18914
18915 MockRead data_reads1[] = {
18916 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18917 // Give a couple authenticate options (only the middle one is actually
18918 // supported).
18919 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18920 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18921 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18922 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18923 // Large content-length -- won't matter, as connection will be reset.
18924 MockRead("Content-Length: 10000\r\n\r\n"),
18925 MockRead(ASYNC, ERR_FAILED),
18926 };
18927
18928 // After calling trans->RestartWithAuth(), this is the request we should
18929 // be issuing -- the final header line contains the credentials.
18930 MockWrite data_writes2[] = {
18931 MockWrite("GET / HTTP/1.1\r\n"
18932 "Host: www.example.org\r\n"
18933 "Connection: keep-alive\r\n"
18934 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18935 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18936 };
18937
18938 // Lastly, the server responds with the actual content.
18939 MockRead data_reads2[] = {
18940 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18941 MockRead("hello world"),
18942 MockRead(SYNCHRONOUS, OK),
18943 };
18944
18945 StaticSocketDataProvider data1(data_reads1, data_writes1);
18946 StaticSocketDataProvider data2(data_reads2, data_writes2);
18947 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18948 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18949
18950 SSLSocketDataProvider ssl1(ASYNC, OK);
18951 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18952 SSLSocketDataProvider ssl2(ASYNC, OK);
18953 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18954
18955 base::TimeTicks start_time = base::TimeTicks::Now();
18956 base::TimeTicks restart_time;
18957
18958 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18959 auto trans =
18960 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18961
18962 TestCompletionCallback callback1;
18963
18964 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18965 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18966
18967 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18968
18969 TestCompletionCallback callback2;
18970
18971 // Wait 10 ms then restart with auth
18972 FastForwardBy(kSleepDuration);
18973 restart_time = base::TimeTicks::Now();
18974 rv =
18975 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18976 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18977
18978 std::string response_data;
18979 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18980 EXPECT_EQ("hello world", response_data);
18981
18982 trans.reset();
18983
18984 // One 401 report for the auth challenge, then a 200 report for the successful
18985 // retry. Note that we don't report the error draining the body, as the first
18986 // request already generated a report for the auth challenge.
18987 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18988
18989 // Check error report contents
18990 CheckReport(0 /* index */, 401 /* status_code */, OK);
18991 CheckReport(1 /* index */, 200 /* status_code */, OK);
18992
18993 const NetworkErrorLoggingService::RequestDetails& error1 =
18994 network_error_logging_service()->errors()[0];
18995 const NetworkErrorLoggingService::RequestDetails& error2 =
18996 network_error_logging_service()->errors()[1];
18997
18998 // Sanity-check elapsed time values
18999 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
19000 // Check that the start time is refreshed when restarting with auth.
19001 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
19002}
19003
19004TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19005 CreateReportRetryKeepAliveConnectionReset) {
19006 std::string extra_header_string = extra_headers_.ToString();
19007 MockWrite data_writes1[] = {
19008 MockWrite("GET / HTTP/1.1\r\n"
19009 "Host: www.example.org\r\n"
19010 "Connection: keep-alive\r\n"),
19011 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19012 MockWrite("GET / HTTP/1.1\r\n"
19013 "Host: www.example.org\r\n"
19014 "Connection: keep-alive\r\n"),
19015 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19016 };
19017
19018 MockRead data_reads1[] = {
19019 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19020 MockRead("hello"),
19021 // Connection is reset
19022 MockRead(ASYNC, ERR_CONNECTION_RESET),
19023 };
19024
19025 // Successful retry
19026 MockRead data_reads2[] = {
19027 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19028 MockRead("world"),
19029 MockRead(ASYNC, OK),
19030 };
19031
19032 StaticSocketDataProvider data1(data_reads1, data_writes1);
19033 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
19034 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19035 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19036
19037 SSLSocketDataProvider ssl1(ASYNC, OK);
19038 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
19039 SSLSocketDataProvider ssl2(ASYNC, OK);
19040 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
19041
19042 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19043 auto trans1 =
19044 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19045
19046 TestCompletionCallback callback1;
19047
19048 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
19049 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19050
19051 std::string response_data;
19052 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19053 EXPECT_EQ("hello", response_data);
19054
19055 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19056
19057 auto trans2 =
19058 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19059
19060 TestCompletionCallback callback2;
19061
19062 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
19063 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19064
19065 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19066 EXPECT_EQ("world", response_data);
19067
19068 trans1.reset();
19069 trans2.reset();
19070
19071 // One OK report from first request, then a ERR_CONNECTION_RESET report from
19072 // the second request, then an OK report from the successful retry.
19073 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19074
19075 // Check error report contents
19076 CheckReport(0 /* index */, 200 /* status_code */, OK);
19077 CheckReport(1 /* index */, 0 /* status_code */, ERR_CONNECTION_RESET);
19078 CheckReport(2 /* index */, 200 /* status_code */, OK);
19079}
19080
19081TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19082 CreateReportRetryKeepAlive408) {
19083 std::string extra_header_string = extra_headers_.ToString();
19084 MockWrite data_writes1[] = {
19085 MockWrite("GET / HTTP/1.1\r\n"
19086 "Host: www.example.org\r\n"
19087 "Connection: keep-alive\r\n"),
19088 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19089 MockWrite("GET / HTTP/1.1\r\n"
19090 "Host: www.example.org\r\n"
19091 "Connection: keep-alive\r\n"),
19092 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19093 };
19094
19095 MockRead data_reads1[] = {
19096 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19097 MockRead("hello"),
19098 // 408 Request Timeout
19099 MockRead(SYNCHRONOUS,
19100 "HTTP/1.1 408 Request Timeout\r\n"
19101 "Connection: Keep-Alive\r\n"
19102 "Content-Length: 6\r\n\r\n"
19103 "Pickle"),
19104 };
19105
19106 // Successful retry
19107 MockRead data_reads2[] = {
19108 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19109 MockRead("world"),
19110 MockRead(ASYNC, OK),
19111 };
19112
19113 StaticSocketDataProvider data1(data_reads1, data_writes1);
19114 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
19115 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19116 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19117
19118 SSLSocketDataProvider ssl1(ASYNC, OK);
19119 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
19120 SSLSocketDataProvider ssl2(ASYNC, OK);
19121 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
19122
19123 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19124 auto trans1 =
19125 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19126
19127 TestCompletionCallback callback1;
19128
19129 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
19130 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19131
19132 std::string response_data;
19133 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19134 EXPECT_EQ("hello", response_data);
19135
19136 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19137
19138 auto trans2 =
19139 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19140
19141 TestCompletionCallback callback2;
19142
19143 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
19144 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19145
19146 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19147 EXPECT_EQ("world", response_data);
19148
19149 trans1.reset();
19150 trans2.reset();
19151
19152 // One 200 report from first request, then a 408 report from
19153 // the second request, then a 200 report from the successful retry.
19154 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19155
19156 // Check error report contents
19157 CheckReport(0 /* index */, 200 /* status_code */, OK);
19158 CheckReport(1 /* index */, 408 /* status_code */, OK);
19159 CheckReport(2 /* index */, 200 /* status_code */, OK);
19160}
19161
19162TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19163 CreateReportRetry421WithoutConnectionPooling) {
19164 // Two hosts resolve to the same IP address.
19165 const std::string ip_addr = "1.2.3.4";
19166 IPAddress ip;
19167 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
19168 IPEndPoint peer_addr = IPEndPoint(ip, 443);
19169
19170 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
19171 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
19172 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
19173
19174 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19175
19176 // Two requests on the first connection.
19177 spdy::SpdySerializedFrame req1(
19178 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
19179 spdy_util_.UpdateWithStreamDestruction(1);
19180 spdy::SpdySerializedFrame req2(
19181 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
19182 spdy::SpdySerializedFrame rst(
19183 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
19184 MockWrite writes1[] = {
19185 CreateMockWrite(req1, 0),
19186 CreateMockWrite(req2, 3),
19187 CreateMockWrite(rst, 6),
19188 };
19189
19190 // The first one succeeds, the second gets error 421 Misdirected Request.
19191 spdy::SpdySerializedFrame resp1(
19192 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
19193 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
19194 spdy::SpdyHeaderBlock response_headers;
19195 response_headers[spdy::kHttp2StatusHeader] = "421";
19196 spdy::SpdySerializedFrame resp2(
19197 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
19198 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
19199 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
19200
19201 MockConnect connect1(ASYNC, OK, peer_addr);
19202 SequencedSocketData data1(connect1, reads1, writes1);
19203 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19204
19205 AddSSLSocketData();
19206
19207 // Retry the second request on a second connection.
19208 SpdyTestUtil spdy_util2;
19209 spdy::SpdySerializedFrame req3(
19210 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
19211 MockWrite writes2[] = {
19212 CreateMockWrite(req3, 0),
19213 };
19214
19215 spdy::SpdySerializedFrame resp3(
19216 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
19217 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
19218 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
19219 MockRead(ASYNC, 0, 3)};
19220
19221 MockConnect connect2(ASYNC, OK, peer_addr);
19222 SequencedSocketData data2(connect2, reads2, writes2);
19223 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19224
19225 AddSSLSocketData();
19226
19227 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3319228 int rv = session_deps_.host_resolver->LoadIntoCache(
19229 HostPortPair("mail.example.com", 443), base::nullopt);
19230 EXPECT_THAT(rv, IsOk());
Lily Chenfec60d92019-01-24 01:16:4219231
19232 HttpRequestInfo request1;
19233 request1.method = "GET";
19234 request1.url = GURL("https://www.example.org/");
19235 request1.load_flags = 0;
19236 request1.traffic_annotation =
19237 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19238 auto trans1 =
19239 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19240
Eric Orthf4db66a2019-02-19 21:35:3319241 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219242 rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
19243 EXPECT_THAT(callback.GetResult(rv), IsOk());
19244
19245 const HttpResponseInfo* response = trans1->GetResponseInfo();
19246 ASSERT_TRUE(response);
19247 ASSERT_TRUE(response->headers);
19248 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19249 EXPECT_TRUE(response->was_fetched_via_spdy);
19250 EXPECT_TRUE(response->was_alpn_negotiated);
19251 std::string response_data;
19252 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19253 EXPECT_EQ("hello!", response_data);
19254
19255 trans1.reset();
19256
19257 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19258
19259 HttpRequestInfo request2;
19260 request2.method = "GET";
19261 request2.url = GURL("https://mail.example.org/");
19262 request2.load_flags = 0;
19263 request2.traffic_annotation =
19264 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19265 auto trans2 =
19266 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19267
19268 BoundTestNetLog log;
19269 rv = trans2->Start(&request2, callback.callback(), log.bound());
19270 EXPECT_THAT(callback.GetResult(rv), IsOk());
19271
19272 response = trans2->GetResponseInfo();
19273 ASSERT_TRUE(response);
19274 ASSERT_TRUE(response->headers);
19275 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19276 EXPECT_TRUE(response->was_fetched_via_spdy);
19277 EXPECT_TRUE(response->was_alpn_negotiated);
19278 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19279 EXPECT_EQ("hello!", response_data);
19280
19281 trans2.reset();
19282
19283 // One 200 report from the first request, then a 421 report from the
19284 // second request, then a 200 report from the successful retry.
19285 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19286
19287 // Check error report contents
19288 const NetworkErrorLoggingService::RequestDetails& error1 =
19289 network_error_logging_service()->errors()[0];
19290 EXPECT_EQ(GURL("https://www.example.org/"), error1.uri);
19291 EXPECT_TRUE(error1.referrer.is_empty());
19292 EXPECT_EQ("", error1.user_agent);
19293 EXPECT_EQ(ip, error1.server_ip);
19294 EXPECT_EQ("h2", error1.protocol);
19295 EXPECT_EQ("GET", error1.method);
19296 EXPECT_EQ(200, error1.status_code);
19297 EXPECT_EQ(OK, error1.type);
19298 EXPECT_EQ(0, error1.reporting_upload_depth);
19299
19300 const NetworkErrorLoggingService::RequestDetails& error2 =
19301 network_error_logging_service()->errors()[1];
19302 EXPECT_EQ(GURL("https://mail.example.org/"), error2.uri);
19303 EXPECT_TRUE(error2.referrer.is_empty());
19304 EXPECT_EQ("", error2.user_agent);
19305 EXPECT_EQ(ip, error2.server_ip);
19306 EXPECT_EQ("h2", error2.protocol);
19307 EXPECT_EQ("GET", error2.method);
19308 EXPECT_EQ(421, error2.status_code);
19309 EXPECT_EQ(OK, error2.type);
19310 EXPECT_EQ(0, error2.reporting_upload_depth);
19311
19312 const NetworkErrorLoggingService::RequestDetails& error3 =
19313 network_error_logging_service()->errors()[2];
19314 EXPECT_EQ(GURL("https://mail.example.org/"), error3.uri);
19315 EXPECT_TRUE(error3.referrer.is_empty());
19316 EXPECT_EQ("", error3.user_agent);
19317 EXPECT_EQ(ip, error3.server_ip);
19318 EXPECT_EQ("h2", error3.protocol);
19319 EXPECT_EQ("GET", error3.method);
19320 EXPECT_EQ(200, error3.status_code);
19321 EXPECT_EQ(OK, error3.type);
19322 EXPECT_EQ(0, error3.reporting_upload_depth);
Douglas Creageref5eecdc2018-11-09 20:50:3619323}
19324
Lily Chend3930e72019-03-01 19:31:1119325TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19326 CreateReportCancelAfterStart) {
19327 StaticSocketDataProvider data;
19328 data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
19329 session_deps_.socket_factory->AddSocketDataProvider(&data);
19330
19331 TestCompletionCallback callback;
19332 auto session = CreateSession(&session_deps_);
19333 auto trans =
19334 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19335 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19336 EXPECT_EQ(rv, ERR_IO_PENDING);
19337
19338 // Cancel after start.
19339 trans.reset();
19340
19341 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19342 CheckReport(0 /* index */, 0 /* status_code */, ERR_ABORTED,
19343 IPAddress() /* server_ip */);
19344}
19345
19346TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19347 CreateReportCancelBeforeReadingBody) {
19348 std::string extra_header_string = extra_headers_.ToString();
19349 MockWrite data_writes[] = {
19350 MockWrite("GET / HTTP/1.1\r\n"
19351 "Host: www.example.org\r\n"
19352 "Connection: keep-alive\r\n"),
19353 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19354 };
19355 MockRead data_reads[] = {
19356 MockRead("HTTP/1.0 200 OK\r\n"),
19357 MockRead("Content-Length: 100\r\n\r\n"), // Body is never read.
19358 };
19359
19360 StaticSocketDataProvider data(data_reads, data_writes);
19361 session_deps_.socket_factory->AddSocketDataProvider(&data);
19362
19363 SSLSocketDataProvider ssl(ASYNC, OK);
19364 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19365
19366 TestCompletionCallback callback;
19367 auto session = CreateSession(&session_deps_);
19368 auto trans =
19369 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19370 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19371 EXPECT_THAT(callback.GetResult(rv), IsOk());
19372
19373 const HttpResponseInfo* response = trans->GetResponseInfo();
19374 ASSERT_TRUE(response);
19375
19376 EXPECT_TRUE(response->headers);
19377 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
19378
19379 // Cancel before reading the body.
19380 trans.reset();
19381
19382 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19383 CheckReport(0 /* index */, 200 /* status_code */, ERR_ABORTED);
19384}
19385
Lily Chen00196ab62018-12-04 19:52:2919386TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) {
19387 base::HistogramTester histograms;
19388 RequestPolicy();
19389 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19390 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19391
19392 // Make HTTP request
19393 std::string extra_header_string = extra_headers_.ToString();
19394 MockRead data_reads[] = {
19395 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
19396 MockRead("hello world"),
19397 MockRead(SYNCHRONOUS, OK),
19398 };
19399 MockWrite data_writes[] = {
19400 MockWrite("GET / HTTP/1.1\r\n"
19401 "Host: www.example.org\r\n"
19402 "Connection: keep-alive\r\n"),
19403 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19404 };
19405
Lily Chend3930e72019-03-01 19:31:1119406 StaticSocketDataProvider data(data_reads, data_writes);
19407 session_deps_.socket_factory->AddSocketDataProvider(&data);
Lily Chen00196ab62018-12-04 19:52:2919408
Lily Chenfec60d92019-01-24 01:16:4219409 // Insecure url
19410 url_ = "http://www.example.org/";
19411 request_.url = GURL(url_);
19412
Lily Chen00196ab62018-12-04 19:52:2919413 TestCompletionCallback callback;
19414 auto session = CreateSession(&session_deps_);
Lily Chenfec60d92019-01-24 01:16:4219415 auto trans =
19416 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19417 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19418 EXPECT_THAT(callback.GetResult(rv), IsOk());
19419
19420 std::string response_data;
19421 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19422 EXPECT_EQ("hello world", response_data);
Lily Chen00196ab62018-12-04 19:52:2919423
19424 // Insecure request does not generate a report
19425 histograms.ExpectBucketCount(
19426 NetworkErrorLoggingService::kRequestOutcomeHistogram,
Tsuyoshi Horo0b042232019-03-06 01:11:0519427 NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1);
Lily Chen00196ab62018-12-04 19:52:2919428
19429 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19430}
19431
19432TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19433 DontCreateReportHttpError) {
19434 base::HistogramTester histograms;
19435 RequestPolicy();
19436 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19437 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19438
19439 // Make HTTP request that fails
19440 MockRead data_reads[] = {
19441 MockRead("hello world"),
19442 MockRead(SYNCHRONOUS, OK),
19443 };
19444
19445 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
19446 session_deps_.socket_factory->AddSocketDataProvider(&data);
19447
Lily Chenfec60d92019-01-24 01:16:4219448 url_ = "http://www.originwithoutpolicy.com:2000/";
19449 request_.url = GURL(url_);
19450
Lily Chen00196ab62018-12-04 19:52:2919451 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19452
Lily Chen00196ab62018-12-04 19:52:2919453 auto trans =
19454 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Lily Chen00196ab62018-12-04 19:52:2919455 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219456 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
Lily Chen00196ab62018-12-04 19:52:2919457 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
19458
19459 // Insecure request does not generate a report, regardless of existence of a
19460 // policy for the origin.
19461 histograms.ExpectBucketCount(
19462 NetworkErrorLoggingService::kRequestOutcomeHistogram,
Tsuyoshi Horo0b042232019-03-06 01:11:0519463 NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1);
Lily Chen00196ab62018-12-04 19:52:2919464
19465 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19466}
19467
Lily Chen90ae93cc2019-02-14 01:15:3919468// Don't report on proxy auth challenges, don't report if connecting through a
19469// proxy.
19470TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportProxy) {
19471 HttpRequestInfo request;
19472 request.method = "GET";
19473 request.url = GURL("https://www.example.org/");
19474 request.traffic_annotation =
19475 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19476
19477 // Configure against proxy server "myproxy:70".
19478 session_deps_.proxy_resolution_service =
19479 ProxyResolutionService::CreateFixedFromPacResult(
19480 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
19481 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19482
19483 // Since we have proxy, should try to establish tunnel.
19484 MockWrite data_writes1[] = {
19485 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19486 "Host: www.example.org:443\r\n"
19487 "Proxy-Connection: keep-alive\r\n\r\n"),
19488 };
19489
19490 // The proxy responds to the connect with a 407, using a non-persistent
19491 // connection.
19492 MockRead data_reads1[] = {
19493 // No credentials.
19494 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
19495 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19496 MockRead("Proxy-Connection: close\r\n\r\n"),
19497 };
19498
19499 MockWrite data_writes2[] = {
19500 // After calling trans->RestartWithAuth(), this is the request we should
19501 // be issuing -- the final header line contains the credentials.
19502 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19503 "Host: www.example.org:443\r\n"
19504 "Proxy-Connection: keep-alive\r\n"
19505 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19506
19507 MockWrite("GET / HTTP/1.1\r\n"
19508 "Host: www.example.org\r\n"
19509 "Connection: keep-alive\r\n\r\n"),
19510 };
19511
19512 MockRead data_reads2[] = {
19513 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
19514
19515 MockRead("HTTP/1.1 200 OK\r\n"),
19516 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19517 MockRead("Content-Length: 5\r\n\r\n"),
19518 MockRead(SYNCHRONOUS, "hello"),
19519 };
19520
19521 StaticSocketDataProvider data1(data_reads1, data_writes1);
19522 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19523 StaticSocketDataProvider data2(data_reads2, data_writes2);
19524 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19525 SSLSocketDataProvider ssl(ASYNC, OK);
19526 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19527
19528 TestCompletionCallback callback1;
19529
19530 auto trans =
19531 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19532
19533 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
19534 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19535
19536 const HttpResponseInfo* response = trans->GetResponseInfo();
19537 EXPECT_EQ(407, response->headers->response_code());
19538
19539 std::string response_data;
19540 rv = ReadTransaction(trans.get(), &response_data);
19541 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
19542
19543 // No NEL report is generated for the 407.
19544 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19545
19546 TestCompletionCallback callback2;
19547
19548 rv =
19549 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
19550 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19551
19552 response = trans->GetResponseInfo();
19553 EXPECT_EQ(200, response->headers->response_code());
19554
19555 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19556 EXPECT_EQ("hello", response_data);
19557
19558 trans.reset();
19559
19560 // No NEL report is generated because we are behind a proxy.
19561 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19562}
19563
Douglas Creageref5eecdc2018-11-09 20:50:3619564TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19565 ReportContainsUploadDepth) {
19566 reporting_upload_depth_ = 7;
Lily Chenfec60d92019-01-24 01:16:4219567 request_.reporting_upload_depth = reporting_upload_depth_;
Douglas Creageref5eecdc2018-11-09 20:50:3619568 RequestPolicy();
19569 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219570 const NetworkErrorLoggingService::RequestDetails& error =
19571 network_error_logging_service()->errors()[0];
Douglas Creageref5eecdc2018-11-09 20:50:3619572 EXPECT_EQ(7, error.reporting_upload_depth);
19573}
19574
Lily Chenfec60d92019-01-24 01:16:4219575TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportElapsedTime) {
19576 std::string extra_header_string = extra_headers_.ToString();
19577 static const base::TimeDelta kSleepDuration =
19578 base::TimeDelta::FromMilliseconds(10);
19579
19580 std::vector<MockWrite> data_writes = {
19581 MockWrite(ASYNC, 0,
19582 "GET / HTTP/1.1\r\n"
19583 "Host: www.example.org\r\n"
19584 "Connection: keep-alive\r\n"),
19585 MockWrite(ASYNC, 1, extra_header_string.data()),
19586 };
19587
19588 std::vector<MockRead> data_reads = {
19589 // Write one byte of the status line, followed by a pause.
19590 MockRead(ASYNC, 2, "H"),
19591 MockRead(ASYNC, ERR_IO_PENDING, 3),
19592 MockRead(ASYNC, 4, "TTP/1.1 200 OK\r\n\r\n"),
19593 MockRead(ASYNC, 5, "hello world"),
19594 MockRead(SYNCHRONOUS, OK, 6),
19595 };
19596
19597 SequencedSocketData data(data_reads, data_writes);
19598 session_deps_.socket_factory->AddSocketDataProvider(&data);
19599
19600 SSLSocketDataProvider ssl(ASYNC, OK);
19601 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19602
19603 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19604
19605 auto trans =
19606 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19607
19608 TestCompletionCallback callback;
19609
19610 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19611 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19612
19613 data.RunUntilPaused();
19614 ASSERT_TRUE(data.IsPaused());
19615 FastForwardBy(kSleepDuration);
19616 data.Resume();
19617
19618 EXPECT_THAT(callback.GetResult(rv), IsOk());
19619
19620 std::string response_data;
19621 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19622 EXPECT_EQ("hello world", response_data);
19623
19624 trans.reset();
19625
Douglas Creageref5eecdc2018-11-09 20:50:3619626 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219627
19628 CheckReport(0 /* index */, 200 /* status_code */, OK);
19629
19630 const NetworkErrorLoggingService::RequestDetails& error =
19631 network_error_logging_service()->errors()[0];
19632
19633 // Sanity-check elapsed time in error report
19634 EXPECT_EQ(kSleepDuration, error.elapsed_time);
Douglas Creageref5eecdc2018-11-09 20:50:3619635}
Lily Chenfec60d92019-01-24 01:16:4219636
Douglas Creager3cb042052018-11-06 23:08:5219637#endif // BUILDFLAG(ENABLE_REPORTING)
19638
[email protected]89ceba9a2009-03-21 03:46:0619639} // namespace net