blob: 295d069d0c6b9a60cc27b230661a212f5f479bbb [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"
[email protected]536fd0b2013-03-14 17:41:5798#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0399#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:57100#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:54101#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:11102#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:01103#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:43104#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:01105#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev27cc7712019-01-24 11:50:14106#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
[email protected]baee31a2018-01-18 06:10:23107#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:00108#include "net/url_request/static_http_user_agent_settings.h"
[email protected]831e4a32013-11-14 02:14:44109#include "net/websockets/websocket_handshake_stream_base.h"
Bence Békydca6bd92018-01-30 13:43:06110#include "net/websockets/websocket_test_util.h"
bncf4588402015-11-24 13:33:18111#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52112#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15113#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27114#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52115
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37116#if defined(NTLM_PORTABLE)
117#include "base/base64.h"
118#include "net/ntlm/ntlm_test_data.h"
119#endif
120
Douglas Creager3cb042052018-11-06 23:08:52121#if BUILDFLAG(ENABLE_REPORTING)
122#include "net/network_error_logging/network_error_logging_service.h"
123#include "net/network_error_logging/network_error_logging_test_util.h"
Douglas Creager134b52e2018-11-09 18:00:14124#include "net/reporting/reporting_cache.h"
125#include "net/reporting/reporting_client.h"
126#include "net/reporting/reporting_header_parser.h"
127#include "net/reporting/reporting_service.h"
128#include "net/reporting/reporting_test_util.h"
Douglas Creager3cb042052018-11-06 23:08:52129#endif // BUILDFLAG(ENABLE_REPORTING)
130
robpercival214763f2016-07-01 23:27:01131using net::test::IsError;
132using net::test::IsOk;
133
[email protected]ad65a3e2013-12-25 18:18:01134using base::ASCIIToUTF16;
135
initial.commit586acc5fe2008-07-26 22:42:52136//-----------------------------------------------------------------------------
137
ttuttle859dc7a2015-04-23 19:42:29138namespace net {
139
[email protected]13c8a092010-07-29 06:15:44140namespace {
141
[email protected]42cba2fb2013-03-29 19:58:57142const base::string16 kBar(ASCIIToUTF16("bar"));
143const base::string16 kBar2(ASCIIToUTF16("bar2"));
144const base::string16 kBar3(ASCIIToUTF16("bar3"));
145const base::string16 kBaz(ASCIIToUTF16("baz"));
146const base::string16 kFirst(ASCIIToUTF16("first"));
147const base::string16 kFoo(ASCIIToUTF16("foo"));
148const base::string16 kFoo2(ASCIIToUTF16("foo2"));
149const base::string16 kFoo3(ASCIIToUTF16("foo3"));
150const base::string16 kFou(ASCIIToUTF16("fou"));
151const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57152const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44153
bnc2df4b522016-07-08 18:17:43154const char kAlternativeServiceHttpHeader[] =
155 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
156
ttuttle859dc7a2015-04-23 19:42:29157int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
Matt Menked23ab952019-03-06 00:24:40158 return session
159 ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
160 ProxyServer::Direct())
ttuttle859dc7a2015-04-23 19:42:29161 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02162}
163
ttuttle859dc7a2015-04-23 19:42:29164bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
Matt Menked23ab952019-03-06 00:24:40165 return session
166 ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
167 ProxyServer::Direct())
ttuttle859dc7a2015-04-23 19:42:29168 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52169}
170
[email protected]f3da152d2012-06-02 01:00:57171// Takes in a Value created from a NetLogHttpResponseParameter, and returns
172// a JSONified list of headers as a single string. Uses single quotes instead
173// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27174bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57175 if (!params)
176 return false;
[email protected]ea5ef4c2013-06-13 22:50:27177 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57178 if (!params->GetList("headers", &header_list))
179 return false;
180 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34181 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28182 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57183 return true;
184}
185
[email protected]029c83b62013-01-24 05:28:20186// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
187// used.
ttuttle859dc7a2015-04-23 19:42:29188void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20189 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19190 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25191
[email protected]029c83b62013-01-24 05:28:20192 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
193 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
194
ttuttle859dc7a2015-04-23 19:42:29195 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20196 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25197
198 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25199
[email protected]3b23a222013-05-15 21:33:25200 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25201 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
202 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25203 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25204}
205
[email protected]029c83b62013-01-24 05:28:20206// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
207// used.
ttuttle859dc7a2015-04-23 19:42:29208void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25209 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20210 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19211 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20212
213 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
214 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
215
ttuttle859dc7a2015-04-23 19:42:29216 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
217 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20218 EXPECT_LE(load_timing_info.connect_timing.connect_end,
219 load_timing_info.send_start);
220
221 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20222
[email protected]3b23a222013-05-15 21:33:25223 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20224 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
225 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25226 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20227}
228
229// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
230// used.
ttuttle859dc7a2015-04-23 19:42:29231void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20232 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19233 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20234
ttuttle859dc7a2015-04-23 19:42:29235 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20236
237 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
238 EXPECT_LE(load_timing_info.proxy_resolve_start,
239 load_timing_info.proxy_resolve_end);
240 EXPECT_LE(load_timing_info.proxy_resolve_end,
241 load_timing_info.send_start);
242 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20243
[email protected]3b23a222013-05-15 21:33:25244 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20245 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
246 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25247 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20248}
249
250// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
251// used.
ttuttle859dc7a2015-04-23 19:42:29252void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20253 int connect_timing_flags) {
254 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19255 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20256
257 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
258 EXPECT_LE(load_timing_info.proxy_resolve_start,
259 load_timing_info.proxy_resolve_end);
260 EXPECT_LE(load_timing_info.proxy_resolve_end,
261 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29262 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
263 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20264 EXPECT_LE(load_timing_info.connect_timing.connect_end,
265 load_timing_info.send_start);
266
267 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20268
[email protected]3b23a222013-05-15 21:33:25269 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20270 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
271 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25272 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25273}
274
Matt Menke2436b2f2018-12-11 18:07:11275// ProxyResolver that records URLs passed to it, and that can be told what
276// result to return.
277class CapturingProxyResolver : public ProxyResolver {
278 public:
279 CapturingProxyResolver()
280 : proxy_server_(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 80)) {}
281 ~CapturingProxyResolver() override = default;
282
283 int GetProxyForURL(const GURL& url,
284 ProxyInfo* results,
285 CompletionOnceCallback callback,
286 std::unique_ptr<Request>* request,
287 const NetLogWithSource& net_log) override {
288 results->UseProxyServer(proxy_server_);
289 resolved_.push_back(url);
290 return OK;
291 }
292
293 // Sets whether the resolver should use direct connections, instead of a
294 // proxy.
295 void set_proxy_server(ProxyServer proxy_server) {
296 proxy_server_ = proxy_server;
297 }
298
299 const std::vector<GURL>& resolved() const { return resolved_; }
300
301 private:
302 std::vector<GURL> resolved_;
303
304 ProxyServer proxy_server_;
305
306 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
307};
308
309class CapturingProxyResolverFactory : public ProxyResolverFactory {
310 public:
311 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
312 : ProxyResolverFactory(false), resolver_(resolver) {}
313
314 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
315 std::unique_ptr<ProxyResolver>* resolver,
316 CompletionOnceCallback callback,
317 std::unique_ptr<Request>* request) override {
318 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
319 return OK;
320 }
321
322 private:
323 ProxyResolver* resolver_;
324};
325
danakj1fd259a02016-04-16 03:17:09326std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42327 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34328 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14329}
330
xunjieli96f2a402017-06-05 17:24:27331class FailingProxyResolverFactory : public ProxyResolverFactory {
332 public:
333 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
334
335 // ProxyResolverFactory override.
Lily Houghton99597862018-03-07 16:40:42336 int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
337 std::unique_ptr<ProxyResolver>* result,
Bence Békycc5b88a2018-05-25 20:24:17338 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:42339 std::unique_ptr<Request>* request) override {
xunjieli96f2a402017-06-05 17:24:27340 return ERR_PAC_SCRIPT_FAILED;
341 }
342};
343
David Benjamin5cb91132018-04-06 05:54:49344class TestSSLConfigService : public SSLConfigService {
345 public:
346 explicit TestSSLConfigService(const SSLConfig& config) : config_(config) {}
Ryan Sleevib8449e02018-07-15 04:31:07347 ~TestSSLConfigService() override = default;
David Benjamin5cb91132018-04-06 05:54:49348
349 void GetSSLConfig(SSLConfig* config) override { *config = config_; }
350
Nick Harper89bc7212018-07-31 19:07:57351 bool CanShareConnectionWithClientCerts(
352 const std::string& hostname) const override {
353 return false;
354 }
355
David Benjamin5cb91132018-04-06 05:54:49356 private:
David Benjamin5cb91132018-04-06 05:54:49357 SSLConfig config_;
358};
359
[email protected]448d4ca52012-03-04 04:12:23360} // namespace
361
Bence Béky98447b12018-05-08 03:14:01362class HttpNetworkTransactionTest : public PlatformTest,
363 public WithScopedTaskEnvironment {
[email protected]483fa202013-05-14 01:07:03364 public:
bncd16676a2016-07-20 16:23:01365 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03366 // Important to restore the per-pool limit first, since the pool limit must
367 // always be greater than group limit, and the tests reduce both limits.
368 ClientSocketPoolManager::set_max_sockets_per_pool(
369 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
370 ClientSocketPoolManager::set_max_sockets_per_group(
371 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
372 }
373
[email protected]e3ceb682011-06-28 23:55:46374 protected:
[email protected]23e482282013-06-14 16:08:02375 HttpNetworkTransactionTest()
Andrew Comminos517a92c2019-01-14 17:49:56376 : WithScopedTaskEnvironment(
377 base::test::ScopedTaskEnvironment::MainThreadType::IO_MOCK_TIME,
378 base::test::ScopedTaskEnvironment::NowSource::
379 MAIN_THREAD_MOCK_TIME),
Matt Menked6fd2a52019-03-20 06:14:36380 dummy_connect_job_params_(
381 nullptr /* client_socket_factory */,
382 nullptr /* host_resolver */,
Matt Menkeb88837e2019-03-20 11:50:40383 nullptr /* http_auth_cache */,
384 nullptr /* http_auth_handler_factory */,
385 nullptr /* spdy_session_pool */,
Matt Menkeb5fb42b2019-03-22 17:26:13386 nullptr /* quic_supported_versions */,
Matt Menkeb88837e2019-03-20 11:50:40387 nullptr /* quic_stream_factory */,
Matt Menked6fd2a52019-03-20 06:14:36388 nullptr /* proxy_delegate */,
389 nullptr /* http_user_agent_settings */,
390 SSLClientSocketContext(),
391 SSLClientSocketContext(),
392 nullptr /* socket_performance_watcher_factory */,
393 nullptr /* network_quality_estimator */,
394 nullptr /* net_log */,
395 nullptr /* websocket_endpoint_lock_manager */),
Andrew Comminos517a92c2019-01-14 17:49:56396 ssl_(ASYNC, OK),
bnc032658ba2016-09-26 18:17:15397 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03398 HttpNetworkSession::NORMAL_SOCKET_POOL)),
399 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
400 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28401 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03402 }
[email protected]bb88e1d32013-05-03 23:11:07403
[email protected]e3ceb682011-06-28 23:55:46404 struct SimpleGetHelperResult {
405 int rv;
406 std::string status_line;
407 std::string response_data;
sclittlefb249892015-09-10 21:33:22408 int64_t total_received_bytes;
409 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25410 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47411 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59412 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46413 };
414
dcheng67be2b1f2014-10-27 21:47:29415 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50416 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55417 base::RunLoop().RunUntilIdle();
Andrew Comminos517a92c2019-01-14 17:49:56418 // Set an initial delay to ensure that the first call to TimeTicks::Now()
419 // before incrementing the counter does not return a null value.
420 FastForwardBy(TimeDelta::FromSeconds(1));
[email protected]2ff8b312010-04-26 22:20:54421 }
422
dcheng67be2b1f2014-10-27 21:47:29423 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50424 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55425 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09426 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55427 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09428 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50429 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55430 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09431 }
432
Andrew Comminos1f2ff1cc2018-12-14 05:22:38433 void Check100ResponseTiming(bool use_spdy);
434
[email protected]202965992011-12-07 23:04:51435 // Either |write_failure| specifies a write failure or |read_failure|
436 // specifies a read failure when using a reused socket. In either case, the
437 // failure should cause the network transaction to resend the request, and the
438 // other argument should be NULL.
439 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
440 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52441
[email protected]a34f61ee2014-03-18 20:59:49442 // Either |write_failure| specifies a write failure or |read_failure|
443 // specifies a read failure when using a reused socket. In either case, the
444 // failure should cause the network transaction to resend the request, and the
445 // other argument should be NULL.
446 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10447 const MockRead* read_failure,
448 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49449
Ryan Sleevib8d7ea02018-05-07 20:01:01450 SimpleGetHelperResult SimpleGetHelperForData(
451 base::span<StaticSocketDataProvider*> providers) {
[email protected]ff007e162009-05-23 09:13:15452 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52453
[email protected]ff007e162009-05-23 09:13:15454 HttpRequestInfo request;
455 request.method = "GET";
bncce36dca22015-04-21 22:11:23456 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10457 request.traffic_annotation =
458 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52459
vishal.b62985ca92015-04-17 08:45:51460 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07461 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09462 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16463 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27464
Ryan Sleevib8d7ea02018-05-07 20:01:01465 for (auto* provider : providers) {
466 session_deps_.socket_factory->AddSocketDataProvider(provider);
[email protected]5a60c8b2011-10-19 20:14:29467 }
initial.commit586acc5fe2008-07-26 22:42:52468
[email protected]49639fa2011-12-20 23:22:41469 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52470
eroman24bc6a12015-05-06 19:55:48471 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16472 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01473 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52474
[email protected]ff007e162009-05-23 09:13:15475 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16476 out.total_received_bytes = trans.GetTotalReceivedBytes();
477 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25478
479 // Even in the failure cases that use this function, connections are always
480 // successfully established before the error.
bnc691fda62016-08-12 00:43:16481 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25482 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
483
[email protected]ff007e162009-05-23 09:13:15484 if (out.rv != OK)
485 return out;
486
bnc691fda62016-08-12 00:43:16487 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50488 // Can't use ASSERT_* inside helper functions like this, so
489 // return an error.
wezca1070932016-05-26 20:30:52490 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50491 out.rv = ERR_UNEXPECTED;
492 return out;
493 }
[email protected]ff007e162009-05-23 09:13:15494 out.status_line = response->headers->GetStatusLine();
495
Tsuyoshi Horo01faed62019-02-20 22:11:37496 EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
497 EXPECT_EQ(80, response->remote_endpoint.port());
[email protected]6d81b482011-02-22 19:47:19498
ttuttled9dbc652015-09-29 20:00:59499 bool got_endpoint =
bnc691fda62016-08-12 00:43:16500 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59501 EXPECT_EQ(got_endpoint,
502 out.remote_endpoint_after_start.address().size() > 0);
503
bnc691fda62016-08-12 00:43:16504 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01505 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40506
mmenke43758e62015-05-04 21:09:46507 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40508 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39509 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00510 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
511 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39512 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00513 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
514 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15515
[email protected]f3da152d2012-06-02 01:00:57516 std::string line;
517 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
518 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
519
[email protected]79e1fd62013-06-20 06:50:04520 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16521 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04522 std::string value;
523 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23524 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04525 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
526 EXPECT_EQ("keep-alive", value);
527
528 std::string response_headers;
529 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23530 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04531 response_headers);
[email protected]3deb9a52010-11-11 00:24:40532
bnc691fda62016-08-12 00:43:16533 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22534 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16535 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22536
bnc691fda62016-08-12 00:43:16537 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47538 return out;
[email protected]ff007e162009-05-23 09:13:15539 }
initial.commit586acc5fe2008-07-26 22:42:52540
Ryan Sleevib8d7ea02018-05-07 20:01:01541 SimpleGetHelperResult SimpleGetHelper(base::span<const MockRead> data_reads) {
sclittlefb249892015-09-10 21:33:22542 MockWrite data_writes[] = {
543 MockWrite("GET / HTTP/1.1\r\n"
544 "Host: www.example.org\r\n"
545 "Connection: keep-alive\r\n\r\n"),
546 };
[email protected]5a60c8b2011-10-19 20:14:29547
Ryan Sleevib8d7ea02018-05-07 20:01:01548 StaticSocketDataProvider reads(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:22549 StaticSocketDataProvider* data[] = {&reads};
Ryan Sleevib8d7ea02018-05-07 20:01:01550 SimpleGetHelperResult out = SimpleGetHelperForData(data);
sclittlefb249892015-09-10 21:33:22551
Ryan Sleevib8d7ea02018-05-07 20:01:01552 EXPECT_EQ(CountWriteBytes(data_writes), out.total_sent_bytes);
sclittlefb249892015-09-10 21:33:22553 return out;
[email protected]b8015c42013-12-24 15:18:19554 }
555
bnc032658ba2016-09-26 18:17:15556 void AddSSLSocketData() {
557 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49558 ssl_.ssl_info.cert =
559 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
560 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15561 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
562 }
563
[email protected]ff007e162009-05-23 09:13:15564 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
565 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52566
[email protected]ff007e162009-05-23 09:13:15567 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07568
[email protected]bb88e1d32013-05-03 23:11:07569 void CheckErrorIsPassedBack(int error, IoMode mode);
570
Matt Menked6fd2a52019-03-20 06:14:36571 const CommonConnectJobParams dummy_connect_job_params_;
572
Douglas Creager134b52e2018-11-09 18:00:14573 // These clocks are defined here, even though they're only used in the
574 // Reporting tests below, since they need to be destroyed after
575 // |session_deps_|.
576 base::SimpleTestClock clock_;
577 base::SimpleTestTickClock tick_clock_;
578
[email protected]4bd46222013-05-14 19:32:23579 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07580 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15581 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03582
583 // Original socket limits. Some tests set these. Safest to always restore
584 // them once each test has been run.
585 int old_max_group_sockets_;
586 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15587};
[email protected]231d5a32008-09-13 00:45:27588
[email protected]448d4ca52012-03-04 04:12:23589namespace {
590
ryansturm49a8cb12016-06-15 16:51:09591class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27592 public:
ryansturm49a8cb12016-06-15 16:51:09593 BeforeHeadersSentHandler()
594 : observed_before_headers_sent_with_proxy_(false),
595 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27596
ryansturm49a8cb12016-06-15 16:51:09597 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
598 HttpRequestHeaders* request_headers) {
599 observed_before_headers_sent_ = true;
600 if (!proxy_info.is_http() && !proxy_info.is_https() &&
601 !proxy_info.is_quic()) {
602 return;
603 }
604 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27605 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
606 }
607
ryansturm49a8cb12016-06-15 16:51:09608 bool observed_before_headers_sent_with_proxy() const {
609 return observed_before_headers_sent_with_proxy_;
610 }
611
612 bool observed_before_headers_sent() const {
613 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27614 }
615
616 std::string observed_proxy_server_uri() const {
617 return observed_proxy_server_uri_;
618 }
619
620 private:
ryansturm49a8cb12016-06-15 16:51:09621 bool observed_before_headers_sent_with_proxy_;
622 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27623 std::string observed_proxy_server_uri_;
624
ryansturm49a8cb12016-06-15 16:51:09625 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27626};
627
[email protected]15a5ccf82008-10-23 19:57:43628// Fill |str| with a long header list that consumes >= |size| bytes.
629void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51630 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19631 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
632 const int sizeof_row = strlen(row);
633 const int num_rows = static_cast<int>(
634 ceil(static_cast<float>(size) / sizeof_row));
635 const int sizeof_data = num_rows * sizeof_row;
636 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43637 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51638
[email protected]4ddaf2502008-10-23 18:26:19639 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43640 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19641}
642
thakis84dff942015-07-28 20:47:38643#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09644uint64_t MockGetMSTime() {
645 // Tue, 23 May 2017 20:13:07 +0000
646 return 131400439870000000;
647}
648
[email protected]385a4672009-03-11 22:21:29649// Alternative functions that eliminate randomness and dependency on the local
650// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37651void MockGenerateRandom(uint8_t* output, size_t n) {
652 // This is set to 0xaa because the client challenge for testing in
653 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
654 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29655}
656
[email protected]fe2bc6a2009-03-23 16:52:20657std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37658 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29659}
thakis84dff942015-07-28 20:47:38660#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29661
Matt Menked6fd2a52019-03-20 06:14:36662class CaptureGroupIdTransportSocketPool : public TransportClientSocketPool {
[email protected]04e5be32009-06-26 20:00:31663 public:
Matt Menked6fd2a52019-03-20 06:14:36664 explicit CaptureGroupIdTransportSocketPool(
665 const CommonConnectJobParams* common_connect_job_params)
666 : TransportClientSocketPool(0,
667 0,
668 base::TimeDelta(),
669 common_connect_job_params,
670 nullptr /* ssl_config_service */) {}
[email protected]e60e47a2010-07-14 03:37:18671
Matt Menkef6edce752019-03-19 17:21:56672 const ClientSocketPool::GroupId& last_group_id_received() const {
673 return last_group_id_;
[email protected]d80a4322009-08-14 07:07:49674 }
675
Tarun Bansal162eabe52018-01-20 01:16:39676 bool socket_requested() const { return socket_requested_; }
677
Matt Menke28ac03e2019-02-25 22:25:50678 int RequestSocket(
Matt Menkef6edce752019-03-19 17:21:56679 const ClientSocketPool::GroupId& group_id,
Matt Menkebd12b7e2019-03-25 21:12:03680 scoped_refptr<ClientSocketPool::SocketParams> socket_params,
Matt Menke28ac03e2019-02-25 22:25:50681 RequestPriority priority,
682 const SocketTag& socket_tag,
683 ClientSocketPool::RespectLimits respect_limits,
684 ClientSocketHandle* handle,
685 CompletionOnceCallback callback,
686 const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback,
687 const NetLogWithSource& net_log) override {
Matt Menkef6edce752019-03-19 17:21:56688 last_group_id_ = group_id;
Tarun Bansal162eabe52018-01-20 01:16:39689 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31690 return ERR_IO_PENDING;
691 }
Matt Menkef6edce752019-03-19 17:21:56692 void CancelRequest(const ClientSocketPool::GroupId& group_id,
dmichaeld6e570d2014-12-18 22:30:57693 ClientSocketHandle* handle) override {}
Matt Menkef6edce752019-03-19 17:21:56694 void ReleaseSocket(const ClientSocketPool::GroupId& group_id,
danakj1fd259a02016-04-16 03:17:09695 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57696 int id) override {}
697 void CloseIdleSockets() override {}
Matt Menkef6edce752019-03-19 17:21:56698 void CloseIdleSocketsInGroup(
699 const ClientSocketPool::GroupId& group_id) override {}
dmichaeld6e570d2014-12-18 22:30:57700 int IdleSocketCount() const override { return 0; }
Matt Menkef6edce752019-03-19 17:21:56701 size_t IdleSocketCountInGroup(
702 const ClientSocketPool::GroupId& group_id) const override {
[email protected]04e5be32009-06-26 20:00:31703 return 0;
704 }
Matt Menkef6edce752019-03-19 17:21:56705 LoadState GetLoadState(const ClientSocketPool::GroupId& group_id,
dmichaeld6e570d2014-12-18 22:30:57706 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31707 return LOAD_STATE_IDLE;
708 }
[email protected]d80a4322009-08-14 07:07:49709
710 private:
Matt Menkef6edce752019-03-19 17:21:56711 ClientSocketPool::GroupId last_group_id_;
Tarun Bansal162eabe52018-01-20 01:16:39712 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31713};
714
[email protected]231d5a32008-09-13 00:45:27715//-----------------------------------------------------------------------------
716
[email protected]79cb5c12011-09-12 13:12:04717// Helper functions for validating that AuthChallengeInfo's are correctly
718// configured for common cases.
719bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
720 if (!auth_challenge)
721 return false;
722 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43723 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04724 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19725 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04726 return true;
727}
728
729bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
730 if (!auth_challenge)
731 return false;
732 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43733 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
734 EXPECT_EQ("MyRealm1", auth_challenge->realm);
735 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
736 return true;
737}
738
739bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
740 if (!auth_challenge)
741 return false;
742 EXPECT_TRUE(auth_challenge->is_proxy);
743 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04744 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19745 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04746 return true;
747}
748
749bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
750 if (!auth_challenge)
751 return false;
752 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43753 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04754 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19755 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04756 return true;
757}
758
thakis84dff942015-07-28 20:47:38759#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04760bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
761 if (!auth_challenge)
762 return false;
763 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55764 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04765 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19766 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04767 return true;
768}
David Benjamin5cb91132018-04-06 05:54:49769
770bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) {
771 if (!auth_challenge)
772 return false;
773 EXPECT_TRUE(auth_challenge->is_proxy);
774 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
775 EXPECT_EQ(std::string(), auth_challenge->realm);
776 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
777 return true;
778}
thakis84dff942015-07-28 20:47:38779#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04780
[email protected]448d4ca52012-03-04 04:12:23781} // namespace
782
bncd16676a2016-07-20 16:23:01783TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09784 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16785 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27786}
787
bncd16676a2016-07-20 16:23:01788TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27789 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35790 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
791 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06792 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27793 };
Ryan Sleevib8d7ea02018-05-07 20:01:01794 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01795 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27796 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
797 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01798 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22799 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47800 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59801
802 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27803}
804
805// Response with no status line.
bncd16676a2016-07-20 16:23:01806TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27807 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35808 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06809 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27810 };
Ryan Sleevib8d7ea02018-05-07 20:01:01811 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41812 EXPECT_THAT(out.rv, IsOk());
813 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
814 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01815 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41816 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27817}
818
mmenkea7da6da2016-09-01 21:56:52819// Response with no status line, and a weird port. Should fail by default.
820TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
821 MockRead data_reads[] = {
822 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
823 };
824
Ryan Sleevib8d7ea02018-05-07 20:01:01825 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52826 session_deps_.socket_factory->AddSocketDataProvider(&data);
827
828 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
829
krasinc06a72a2016-12-21 03:42:46830 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58831 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19832 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52833
mmenkea7da6da2016-09-01 21:56:52834 request.method = "GET";
835 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10836 request.traffic_annotation =
837 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
838
mmenkea7da6da2016-09-01 21:56:52839 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20840 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52841 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
842}
843
Shivani Sharmafdcaefd2017-11-02 00:12:26844// Tests that request info can be destroyed after the headers phase is complete.
845TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
846 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
847 auto trans =
848 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
849
850 MockRead data_reads[] = {
851 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
852 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
853 };
Ryan Sleevib8d7ea02018-05-07 20:01:01854 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Shivani Sharmafdcaefd2017-11-02 00:12:26855 session_deps_.socket_factory->AddSocketDataProvider(&data);
856
857 TestCompletionCallback callback;
858
859 {
860 auto request = std::make_unique<HttpRequestInfo>();
861 request->method = "GET";
862 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10863 request->traffic_annotation =
864 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26865
866 int rv =
867 trans->Start(request.get(), callback.callback(), NetLogWithSource());
868
869 EXPECT_THAT(callback.GetResult(rv), IsOk());
870 } // Let request info be destroyed.
871
872 trans.reset();
873}
874
mmenkea7da6da2016-09-01 21:56:52875// Response with no status line, and a weird port. Option to allow weird ports
876// enabled.
877TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
878 MockRead data_reads[] = {
879 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
880 };
881
Ryan Sleevib8d7ea02018-05-07 20:01:01882 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52883 session_deps_.socket_factory->AddSocketDataProvider(&data);
884 session_deps_.http_09_on_non_default_ports_enabled = true;
885 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
886
krasinc06a72a2016-12-21 03:42:46887 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58888 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19889 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52890
mmenkea7da6da2016-09-01 21:56:52891 request.method = "GET";
892 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10893 request.traffic_annotation =
894 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
895
mmenkea7da6da2016-09-01 21:56:52896 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20897 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52898 EXPECT_THAT(callback.GetResult(rv), IsOk());
899
900 const HttpResponseInfo* info = trans->GetResponseInfo();
901 ASSERT_TRUE(info->headers);
902 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
903
904 // Don't bother to read the body - that's verified elsewhere, important thing
905 // is that the option to allow HTTP/0.9 on non-default ports is respected.
906}
907
[email protected]231d5a32008-09-13 00:45:27908// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01909TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27910 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35911 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06912 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27913 };
Ryan Sleevib8d7ea02018-05-07 20:01:01914 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01915 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27916 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
917 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01918 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22919 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27920}
921
922// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01923TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27924 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35925 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06926 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27927 };
Ryan Sleevib8d7ea02018-05-07 20:01:01928 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01929 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27930 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
931 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01932 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22933 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27934}
935
936// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01937TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27938 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35939 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06940 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27941 };
Ryan Sleevib8d7ea02018-05-07 20:01:01942 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41943 EXPECT_THAT(out.rv, IsOk());
944 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
945 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01946 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41947 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27948}
949
950// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01951TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27952 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35953 MockRead("\n"),
954 MockRead("\n"),
955 MockRead("Q"),
956 MockRead("J"),
957 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06958 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27959 };
Ryan Sleevib8d7ea02018-05-07 20:01:01960 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01961 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27962 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
963 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01964 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22965 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27966}
967
968// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01969TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27970 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35971 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06972 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27973 };
Ryan Sleevib8d7ea02018-05-07 20:01:01974 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41975 EXPECT_THAT(out.rv, IsOk());
976 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
977 EXPECT_EQ("HTT", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01978 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41979 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52980}
981
[email protected]f9d44aa2008-09-23 23:57:17982// Simulate a 204 response, lacking a Content-Length header, sent over a
983// persistent connection. The response should still terminate since a 204
984// cannot have a response body.
bncd16676a2016-07-20 16:23:01985TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19986 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17987 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35988 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19989 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06990 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17991 };
Ryan Sleevib8d7ea02018-05-07 20:01:01992 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01993 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17994 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
995 EXPECT_EQ("", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01996 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22997 int64_t response_size = reads_size - strlen(junk);
998 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17999}
1000
[email protected]0877e3d2009-10-17 22:29:571001// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011002TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191003 std::string final_chunk = "0\r\n\r\n";
1004 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1005 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571006 MockRead data_reads[] = {
1007 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1008 MockRead("5\r\nHello\r\n"),
1009 MockRead("1\r\n"),
1010 MockRead(" \r\n"),
1011 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191012 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061013 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571014 };
Ryan Sleevib8d7ea02018-05-07 20:01:011015 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011016 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571017 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1018 EXPECT_EQ("Hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011019 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221020 int64_t response_size = reads_size - extra_data.size();
1021 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571022}
1023
[email protected]9fe44f52010-09-23 18:36:001024// Next tests deal with http://crbug.com/56344.
1025
bncd16676a2016-07-20 16:23:011026TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001027 MultipleContentLengthHeadersNoTransferEncoding) {
1028 MockRead data_reads[] = {
1029 MockRead("HTTP/1.1 200 OK\r\n"),
1030 MockRead("Content-Length: 10\r\n"),
1031 MockRead("Content-Length: 5\r\n\r\n"),
1032 };
Ryan Sleevib8d7ea02018-05-07 20:01:011033 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011034 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001035}
1036
bncd16676a2016-07-20 16:23:011037TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041038 DuplicateContentLengthHeadersNoTransferEncoding) {
1039 MockRead data_reads[] = {
1040 MockRead("HTTP/1.1 200 OK\r\n"),
1041 MockRead("Content-Length: 5\r\n"),
1042 MockRead("Content-Length: 5\r\n\r\n"),
1043 MockRead("Hello"),
1044 };
Ryan Sleevib8d7ea02018-05-07 20:01:011045 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011046 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041047 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1048 EXPECT_EQ("Hello", out.response_data);
1049}
1050
bncd16676a2016-07-20 16:23:011051TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041052 ComplexContentLengthHeadersNoTransferEncoding) {
1053 // More than 2 dupes.
1054 {
1055 MockRead data_reads[] = {
1056 MockRead("HTTP/1.1 200 OK\r\n"),
1057 MockRead("Content-Length: 5\r\n"),
1058 MockRead("Content-Length: 5\r\n"),
1059 MockRead("Content-Length: 5\r\n\r\n"),
1060 MockRead("Hello"),
1061 };
Ryan Sleevib8d7ea02018-05-07 20:01:011062 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011063 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041064 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1065 EXPECT_EQ("Hello", out.response_data);
1066 }
1067 // HTTP/1.0
1068 {
1069 MockRead data_reads[] = {
1070 MockRead("HTTP/1.0 200 OK\r\n"),
1071 MockRead("Content-Length: 5\r\n"),
1072 MockRead("Content-Length: 5\r\n"),
1073 MockRead("Content-Length: 5\r\n\r\n"),
1074 MockRead("Hello"),
1075 };
Ryan Sleevib8d7ea02018-05-07 20:01:011076 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011077 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041078 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1079 EXPECT_EQ("Hello", out.response_data);
1080 }
1081 // 2 dupes and one mismatched.
1082 {
1083 MockRead data_reads[] = {
1084 MockRead("HTTP/1.1 200 OK\r\n"),
1085 MockRead("Content-Length: 10\r\n"),
1086 MockRead("Content-Length: 10\r\n"),
1087 MockRead("Content-Length: 5\r\n\r\n"),
1088 };
Ryan Sleevib8d7ea02018-05-07 20:01:011089 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011090 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041091 }
1092}
1093
bncd16676a2016-07-20 16:23:011094TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001095 MultipleContentLengthHeadersTransferEncoding) {
1096 MockRead data_reads[] = {
1097 MockRead("HTTP/1.1 200 OK\r\n"),
1098 MockRead("Content-Length: 666\r\n"),
1099 MockRead("Content-Length: 1337\r\n"),
1100 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1101 MockRead("5\r\nHello\r\n"),
1102 MockRead("1\r\n"),
1103 MockRead(" \r\n"),
1104 MockRead("5\r\nworld\r\n"),
1105 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061106 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001107 };
Ryan Sleevib8d7ea02018-05-07 20:01:011108 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011109 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001110 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1111 EXPECT_EQ("Hello world", out.response_data);
1112}
1113
[email protected]1628fe92011-10-04 23:04:551114// Next tests deal with http://crbug.com/98895.
1115
1116// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011117TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551118 MockRead data_reads[] = {
1119 MockRead("HTTP/1.1 200 OK\r\n"),
1120 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1121 MockRead("Content-Length: 5\r\n\r\n"),
1122 MockRead("Hello"),
1123 };
Ryan Sleevib8d7ea02018-05-07 20:01:011124 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011125 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551126 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1127 EXPECT_EQ("Hello", out.response_data);
1128}
1129
[email protected]54a9c6e52012-03-21 20:10:591130// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011131TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551132 MockRead data_reads[] = {
1133 MockRead("HTTP/1.1 200 OK\r\n"),
1134 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1135 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1136 MockRead("Content-Length: 5\r\n\r\n"),
1137 MockRead("Hello"),
1138 };
Ryan Sleevib8d7ea02018-05-07 20:01:011139 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011140 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591141 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1142 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551143}
1144
1145// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011146TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551147 MockRead data_reads[] = {
1148 MockRead("HTTP/1.1 200 OK\r\n"),
1149 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1150 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1151 MockRead("Content-Length: 5\r\n\r\n"),
1152 MockRead("Hello"),
1153 };
Ryan Sleevib8d7ea02018-05-07 20:01:011154 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011155 EXPECT_THAT(out.rv,
1156 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551157}
1158
[email protected]54a9c6e52012-03-21 20:10:591159// Checks that two identical Location headers result in no error.
1160// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011161TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551162 MockRead data_reads[] = {
1163 MockRead("HTTP/1.1 302 Redirect\r\n"),
1164 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591165 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551166 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061167 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551168 };
1169
1170 HttpRequestInfo request;
1171 request.method = "GET";
1172 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101173 request.traffic_annotation =
1174 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551175
danakj1fd259a02016-04-16 03:17:091176 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161177 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551178
Ryan Sleevib8d7ea02018-05-07 20:01:011179 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071180 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551181
[email protected]49639fa2011-12-20 23:22:411182 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551183
tfarina42834112016-09-22 13:38:201184 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011185 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551186
robpercival214763f2016-07-01 23:27:011187 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551188
bnc691fda62016-08-12 00:43:161189 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521190 ASSERT_TRUE(response);
1191 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551192 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1193 std::string url;
1194 EXPECT_TRUE(response->headers->IsRedirect(&url));
1195 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471196 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551197}
1198
[email protected]1628fe92011-10-04 23:04:551199// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011200TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551201 MockRead data_reads[] = {
1202 MockRead("HTTP/1.1 302 Redirect\r\n"),
1203 MockRead("Location: http://good.com/\r\n"),
1204 MockRead("Location: http://evil.com/\r\n"),
1205 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061206 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551207 };
Ryan Sleevib8d7ea02018-05-07 20:01:011208 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011209 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551210}
1211
[email protected]ef0faf2e72009-03-05 23:27:231212// Do a request using the HEAD method. Verify that we don't try to read the
1213// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011214TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421215 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231216 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231217 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101218 request.traffic_annotation =
1219 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231220
danakj1fd259a02016-04-16 03:17:091221 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161222 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091223 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161224 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091225 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1226 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271227
[email protected]ef0faf2e72009-03-05 23:27:231228 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131229 MockWrite("HEAD / HTTP/1.1\r\n"
1230 "Host: www.example.org\r\n"
1231 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231232 };
1233 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231234 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1235 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231236
mmenked39192ee2015-12-09 00:57:231237 // No response body because the test stops reading here.
1238 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231239 };
1240
Ryan Sleevib8d7ea02018-05-07 20:01:011241 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:071242 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231243
[email protected]49639fa2011-12-20 23:22:411244 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231245
tfarina42834112016-09-22 13:38:201246 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011247 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231248
1249 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011250 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231251
bnc691fda62016-08-12 00:43:161252 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521253 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231254
1255 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521256 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231257 EXPECT_EQ(1234, response->headers->GetContentLength());
1258 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471259 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091260 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1261 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231262
1263 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101264 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231265 bool has_server_header = response->headers->EnumerateHeader(
1266 &iter, "Server", &server_header);
1267 EXPECT_TRUE(has_server_header);
1268 EXPECT_EQ("Blah", server_header);
1269
1270 // Reading should give EOF right away, since there is no message body
1271 // (despite non-zero content-length).
1272 std::string response_data;
bnc691fda62016-08-12 00:43:161273 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011274 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231275 EXPECT_EQ("", response_data);
1276}
1277
bncd16676a2016-07-20 16:23:011278TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091279 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521280
1281 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351282 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1283 MockRead("hello"),
1284 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1285 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061286 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521287 };
Ryan Sleevib8d7ea02018-05-07 20:01:011288 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071289 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521290
[email protected]0b0bf032010-09-21 18:08:501291 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521292 "hello", "world"
1293 };
1294
1295 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421296 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521297 request.method = "GET";
bncce36dca22015-04-21 22:11:231298 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101299 request.traffic_annotation =
1300 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521301
bnc691fda62016-08-12 00:43:161302 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271303
[email protected]49639fa2011-12-20 23:22:411304 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521305
tfarina42834112016-09-22 13:38:201306 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011307 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521308
1309 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011310 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521311
bnc691fda62016-08-12 00:43:161312 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521313 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521314
wezca1070932016-05-26 20:30:521315 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251316 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471317 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521318
1319 std::string response_data;
bnc691fda62016-08-12 00:43:161320 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011321 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251322 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521323 }
1324}
1325
bncd16676a2016-07-20 16:23:011326TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091327 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221328 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191329 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221330 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271331
[email protected]1c773ea12009-04-28 19:58:421332 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521333 request.method = "POST";
1334 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271335 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:101336 request.traffic_annotation =
1337 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521338
shivanishab9a143952016-09-19 17:23:411339 // Check the upload progress returned before initialization is correct.
1340 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1341 EXPECT_EQ(0u, progress.size());
1342 EXPECT_EQ(0u, progress.position());
1343
danakj1fd259a02016-04-16 03:17:091344 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161345 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271346
initial.commit586acc5fe2008-07-26 22:42:521347 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351348 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1349 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1350 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061351 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521352 };
Ryan Sleevib8d7ea02018-05-07 20:01:011353 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071354 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521355
[email protected]49639fa2011-12-20 23:22:411356 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521357
tfarina42834112016-09-22 13:38:201358 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011359 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521360
1361 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011362 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521363
bnc691fda62016-08-12 00:43:161364 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521365 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521366
wezca1070932016-05-26 20:30:521367 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251368 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521369
1370 std::string response_data;
bnc691fda62016-08-12 00:43:161371 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011372 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251373 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521374}
1375
[email protected]3a2d3662009-03-27 03:49:141376// This test is almost the same as Ignores100 above, but the response contains
1377// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571378// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011379TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421380 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141381 request.method = "GET";
1382 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101383 request.traffic_annotation =
1384 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141385
danakj1fd259a02016-04-16 03:17:091386 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161387 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271388
[email protected]3a2d3662009-03-27 03:49:141389 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571390 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1391 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141392 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061393 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141394 };
Ryan Sleevib8d7ea02018-05-07 20:01:011395 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071396 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141397
[email protected]49639fa2011-12-20 23:22:411398 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141399
tfarina42834112016-09-22 13:38:201400 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011401 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141402
1403 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011404 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141405
bnc691fda62016-08-12 00:43:161406 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521407 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141408
wezca1070932016-05-26 20:30:521409 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141410 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1411
1412 std::string response_data;
bnc691fda62016-08-12 00:43:161413 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011414 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141415 EXPECT_EQ("hello world", response_data);
1416}
1417
Andrew Comminos517a92c2019-01-14 17:49:561418TEST_F(HttpNetworkTransactionTest, LoadTimingMeasuresTimeToFirstByteForHttp) {
1419 static const base::TimeDelta kDelayAfterFirstByte =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381420 base::TimeDelta::FromMilliseconds(10);
1421
1422 HttpRequestInfo request;
1423 request.method = "GET";
1424 request.url = GURL("http://www.foo.com/");
1425 request.traffic_annotation =
1426 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1427
1428 std::vector<MockWrite> data_writes = {
1429 MockWrite(ASYNC, 0,
1430 "GET / HTTP/1.1\r\n"
1431 "Host: www.foo.com\r\n"
1432 "Connection: keep-alive\r\n\r\n"),
1433 };
1434
1435 std::vector<MockRead> data_reads = {
1436 // Write one byte of the status line, followed by a pause.
1437 MockRead(ASYNC, 1, "H"),
1438 MockRead(ASYNC, ERR_IO_PENDING, 2),
1439 MockRead(ASYNC, 3, "TTP/1.1 200 OK\r\n\r\n"),
1440 MockRead(ASYNC, 4, "hello world"),
1441 MockRead(SYNCHRONOUS, OK, 5),
1442 };
1443
1444 SequencedSocketData data(data_reads, data_writes);
1445 session_deps_.socket_factory->AddSocketDataProvider(&data);
1446
1447 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1448
1449 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1450
1451 TestCompletionCallback callback;
1452
1453 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1454 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1455
1456 data.RunUntilPaused();
1457 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561458 FastForwardBy(kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381459 data.Resume();
1460
1461 rv = callback.WaitForResult();
1462 EXPECT_THAT(rv, IsOk());
1463
1464 const HttpResponseInfo* response = trans.GetResponseInfo();
1465 ASSERT_TRUE(response);
1466
1467 EXPECT_TRUE(response->headers);
1468 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1469
1470 LoadTimingInfo load_timing_info;
1471 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1472 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1473 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561474 // Ensure we didn't include the delay in the TTFB time.
1475 EXPECT_EQ(load_timing_info.receive_headers_start,
1476 load_timing_info.connect_timing.connect_end);
1477 // Ensure that the mock clock advanced at all.
1478 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1479 kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381480
1481 std::string response_data;
1482 rv = ReadTransaction(&trans, &response_data);
1483 EXPECT_THAT(rv, IsOk());
1484 EXPECT_EQ("hello world", response_data);
1485}
1486
1487// Tests that the time-to-first-byte reported in a transaction's load timing
1488// info uses the first response, even if 1XX/informational.
1489void HttpNetworkTransactionTest::Check100ResponseTiming(bool use_spdy) {
Andrew Comminos517a92c2019-01-14 17:49:561490 static const base::TimeDelta kDelayAfter100Response =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381491 base::TimeDelta::FromMilliseconds(10);
1492
1493 HttpRequestInfo request;
1494 request.method = "GET";
1495 request.url = GURL("https://www.foo.com/");
1496 request.traffic_annotation =
1497 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1498
1499 SSLSocketDataProvider ssl(ASYNC, OK);
1500 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1501
1502 std::vector<MockWrite> data_writes;
1503 std::vector<MockRead> data_reads;
1504
1505 spdy::SpdySerializedFrame spdy_req(
1506 spdy_util_.ConstructSpdyGet(request.url.spec().c_str(), 1, LOWEST));
1507
1508 spdy::SpdyHeaderBlock spdy_resp1_headers;
1509 spdy_resp1_headers[spdy::kHttp2StatusHeader] = "100";
1510 spdy::SpdySerializedFrame spdy_resp1(
1511 spdy_util_.ConstructSpdyReply(1, spdy_resp1_headers.Clone()));
1512 spdy::SpdySerializedFrame spdy_resp2(
1513 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1514 spdy::SpdySerializedFrame spdy_data(
1515 spdy_util_.ConstructSpdyDataFrame(1, "hello world", true));
1516
1517 if (use_spdy) {
1518 ssl.next_proto = kProtoHTTP2;
1519
1520 data_writes = {CreateMockWrite(spdy_req, 0)};
1521
1522 data_reads = {
1523 CreateMockRead(spdy_resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
1524 CreateMockRead(spdy_resp2, 3), CreateMockRead(spdy_data, 4),
1525 MockRead(SYNCHRONOUS, OK, 5),
1526 };
1527 } else {
1528 data_writes = {
1529 MockWrite(ASYNC, 0,
1530 "GET / HTTP/1.1\r\n"
1531 "Host: www.foo.com\r\n"
1532 "Connection: keep-alive\r\n\r\n"),
1533 };
1534
1535 data_reads = {
1536 MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
1537 MockRead(ASYNC, ERR_IO_PENDING, 2),
1538
1539 MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1540 MockRead(ASYNC, 4, "hello world"),
1541 MockRead(SYNCHRONOUS, OK, 5),
1542 };
1543 }
1544
1545 SequencedSocketData data(data_reads, data_writes);
1546 session_deps_.socket_factory->AddSocketDataProvider(&data);
1547
1548 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1549
1550 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1551
1552 TestCompletionCallback callback;
1553
1554 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1556
1557 data.RunUntilPaused();
1558 // We should now have parsed the 100 response and hit ERR_IO_PENDING. Insert
1559 // the delay before parsing the 200 response.
1560 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561561 FastForwardBy(kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381562 data.Resume();
1563
1564 rv = callback.WaitForResult();
1565 EXPECT_THAT(rv, IsOk());
1566
1567 const HttpResponseInfo* response = trans.GetResponseInfo();
1568 ASSERT_TRUE(response);
1569
1570 LoadTimingInfo load_timing_info;
1571 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1572 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1573 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561574 // Ensure we didn't include the delay in the TTFB time.
1575 EXPECT_EQ(load_timing_info.receive_headers_start,
1576 load_timing_info.connect_timing.connect_end);
1577 // Ensure that the mock clock advanced at all.
1578 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1579 kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381580
1581 std::string response_data;
1582 rv = ReadTransaction(&trans, &response_data);
1583 EXPECT_THAT(rv, IsOk());
1584 EXPECT_EQ("hello world", response_data);
1585}
1586
Andrew Comminos517a92c2019-01-14 17:49:561587TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForHttp) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381588 Check100ResponseTiming(false /* use_spdy */);
1589}
1590
Andrew Comminos517a92c2019-01-14 17:49:561591TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForSpdy) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381592 Check100ResponseTiming(true /* use_spdy */);
1593}
1594
bncd16676a2016-07-20 16:23:011595TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081596 HttpRequestInfo request;
1597 request.method = "POST";
1598 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101599 request.traffic_annotation =
1600 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081601
danakj1fd259a02016-04-16 03:17:091602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081604
1605 MockRead data_reads[] = {
1606 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1607 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381608 };
Ryan Sleevib8d7ea02018-05-07 20:01:011609 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
zmo9528c9f42015-08-04 22:12:081610 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381611
zmo9528c9f42015-08-04 22:12:081612 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381613
tfarina42834112016-09-22 13:38:201614 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011615 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381616
zmo9528c9f42015-08-04 22:12:081617 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011618 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381619
zmo9528c9f42015-08-04 22:12:081620 std::string response_data;
bnc691fda62016-08-12 00:43:161621 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011622 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081623 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381624}
1625
bncd16676a2016-07-20 16:23:011626TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381627 HttpRequestInfo request;
1628 request.method = "POST";
1629 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101630 request.traffic_annotation =
1631 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381632
danakj1fd259a02016-04-16 03:17:091633 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161634 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271635
[email protected]ee9410e72010-01-07 01:42:381636 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061637 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381638 };
Ryan Sleevib8d7ea02018-05-07 20:01:011639 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071640 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381641
[email protected]49639fa2011-12-20 23:22:411642 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381643
tfarina42834112016-09-22 13:38:201644 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011645 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381646
1647 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011648 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381649}
1650
[email protected]23e482282013-06-14 16:08:021651void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511652 const MockWrite* write_failure,
1653 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421654 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521655 request.method = "GET";
1656 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101657 request.traffic_annotation =
1658 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521659
vishal.b62985ca92015-04-17 08:45:511660 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071661 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091662 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271663
[email protected]202965992011-12-07 23:04:511664 // Written data for successfully sending both requests.
1665 MockWrite data1_writes[] = {
1666 MockWrite("GET / HTTP/1.1\r\n"
1667 "Host: www.foo.com\r\n"
1668 "Connection: keep-alive\r\n\r\n"),
1669 MockWrite("GET / HTTP/1.1\r\n"
1670 "Host: www.foo.com\r\n"
1671 "Connection: keep-alive\r\n\r\n")
1672 };
1673
1674 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521675 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351676 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1677 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061678 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521679 };
[email protected]202965992011-12-07 23:04:511680
1681 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491682 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511683 data1_writes[1] = *write_failure;
1684 } else {
1685 ASSERT_TRUE(read_failure);
1686 data1_reads[2] = *read_failure;
1687 }
1688
Ryan Sleevib8d7ea02018-05-07 20:01:011689 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]bb88e1d32013-05-03 23:11:071690 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521691
1692 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351693 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1694 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061695 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521696 };
Ryan Sleevib8d7ea02018-05-07 20:01:011697 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071698 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521699
thestig9d3bb0c2015-01-24 00:49:511700 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521701 "hello", "world"
1702 };
1703
mikecironef22f9812016-10-04 03:40:191704 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521705 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411706 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521707
bnc691fda62016-08-12 00:43:161708 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521709
tfarina42834112016-09-22 13:38:201710 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521712
1713 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011714 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521715
[email protected]58e32bb2013-01-21 18:23:251716 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161717 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251718 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1719 if (i == 0) {
1720 first_socket_log_id = load_timing_info.socket_log_id;
1721 } else {
1722 // The second request should be using a new socket.
1723 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1724 }
1725
bnc691fda62016-08-12 00:43:161726 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521727 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521728
wezca1070932016-05-26 20:30:521729 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471730 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251731 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521732
1733 std::string response_data;
bnc691fda62016-08-12 00:43:161734 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011735 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251736 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521737 }
1738}
[email protected]3d2a59b2008-09-26 19:44:251739
[email protected]a34f61ee2014-03-18 20:59:491740void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1741 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101742 const MockRead* read_failure,
1743 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491744 HttpRequestInfo request;
1745 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101746 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101747 request.traffic_annotation =
1748 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491749
vishal.b62985ca92015-04-17 08:45:511750 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491751 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091752 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491753
[email protected]09356c652014-03-25 15:36:101754 SSLSocketDataProvider ssl1(ASYNC, OK);
1755 SSLSocketDataProvider ssl2(ASYNC, OK);
1756 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361757 ssl1.next_proto = kProtoHTTP2;
1758 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101759 }
1760 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1761 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491762
[email protected]09356c652014-03-25 15:36:101763 // SPDY versions of the request and response.
Ryan Hamilton0239aac2018-05-19 00:03:131764 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491765 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131766 spdy::SpdySerializedFrame spdy_response(
Raul Tambre94493c652019-03-11 17:18:351767 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131768 spdy::SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191769 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491770
[email protected]09356c652014-03-25 15:36:101771 // HTTP/1.1 versions of the request and response.
1772 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1773 "Host: www.foo.com\r\n"
1774 "Connection: keep-alive\r\n\r\n";
1775 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1776 const char kHttpData[] = "hello";
1777
1778 std::vector<MockRead> data1_reads;
1779 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491780 if (write_failure) {
1781 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101782 data1_writes.push_back(*write_failure);
1783 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491784 } else {
1785 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101786 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411787 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101788 } else {
1789 data1_writes.push_back(MockWrite(kHttpRequest));
1790 }
1791 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491792 }
1793
Ryan Sleevib8d7ea02018-05-07 20:01:011794 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]a34f61ee2014-03-18 20:59:491795 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1796
[email protected]09356c652014-03-25 15:36:101797 std::vector<MockRead> data2_reads;
1798 std::vector<MockWrite> data2_writes;
1799
1800 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411801 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101802
bncdf80d44fd2016-07-15 20:27:411803 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1804 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101805 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1806 } else {
1807 data2_writes.push_back(
1808 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1809
1810 data2_reads.push_back(
1811 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1812 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1813 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1814 }
Ryan Sleevib8d7ea02018-05-07 20:01:011815 SequencedSocketData data2(data2_reads, data2_writes);
[email protected]a34f61ee2014-03-18 20:59:491816 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1817
1818 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591819 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491820 // Wait for the preconnect to complete.
1821 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1822 base::RunLoop().RunUntilIdle();
Matt Menke9d5e2c92019-02-05 01:42:231823 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491824
1825 // Make the request.
1826 TestCompletionCallback callback;
1827
bnc691fda62016-08-12 00:43:161828 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491829
tfarina42834112016-09-22 13:38:201830 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011831 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491832
1833 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011834 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491835
1836 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161837 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101838 TestLoadTimingNotReused(
1839 load_timing_info,
1840 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491841
bnc691fda62016-08-12 00:43:161842 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521843 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491844
wezca1070932016-05-26 20:30:521845 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021846 if (response->was_fetched_via_spdy) {
1847 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1848 } else {
1849 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1850 }
[email protected]a34f61ee2014-03-18 20:59:491851
1852 std::string response_data;
bnc691fda62016-08-12 00:43:161853 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011854 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101855 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491856}
1857
Biljith Jayan45a41722017-08-16 18:43:141858// Test that we do not retry indefinitely when a server sends an error like
1859// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1860// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1861TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1862 HttpRequestInfo request;
1863 request.method = "GET";
1864 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101865 request.traffic_annotation =
1866 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141867
1868 // Check whether we give up after the third try.
1869
1870 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131871 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141872 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131873 spdy::SpdySerializedFrame spdy_response_go_away(
1874 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011875 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1876 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141877
1878 // Three go away responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011879 StaticSocketDataProvider data1(data_read1, data_write);
1880 StaticSocketDataProvider data2(data_read1, data_write);
1881 StaticSocketDataProvider data3(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141882
1883 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1884 AddSSLSocketData();
1885 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1886 AddSSLSocketData();
1887 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1888 AddSSLSocketData();
1889
1890 TestCompletionCallback callback;
1891 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1892 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1893
1894 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1896
1897 rv = callback.WaitForResult();
1898 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1899}
1900
1901TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1902 HttpRequestInfo request;
1903 request.method = "GET";
1904 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101905 request.traffic_annotation =
1906 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141907
1908 // Check whether we try atleast thrice before giving up.
1909
1910 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131911 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141912 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131913 spdy::SpdySerializedFrame spdy_response_go_away(
1914 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011915 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1916 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141917
1918 // Construct a non error HTTP2 response.
Ryan Hamilton0239aac2018-05-19 00:03:131919 spdy::SpdySerializedFrame spdy_response_no_error(
Biljith Jayan45a41722017-08-16 18:43:141920 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131921 spdy::SpdySerializedFrame spdy_data(
1922 spdy_util_.ConstructSpdyDataFrame(1, true));
Biljith Jayan45a41722017-08-16 18:43:141923 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1924 CreateMockRead(spdy_data, 2)};
1925
1926 // Two error responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011927 StaticSocketDataProvider data1(data_read1, data_write);
1928 StaticSocketDataProvider data2(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141929 // Followed by a success response.
Ryan Sleevib8d7ea02018-05-07 20:01:011930 SequencedSocketData data3(data_read2, data_write);
Biljith Jayan45a41722017-08-16 18:43:141931
1932 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1933 AddSSLSocketData();
1934 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1935 AddSSLSocketData();
1936 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1937 AddSSLSocketData();
1938
1939 TestCompletionCallback callback;
1940 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1941 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1942
1943 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1945
1946 rv = callback.WaitForResult();
1947 EXPECT_THAT(rv, IsOk());
1948}
1949
bncd16676a2016-07-20 16:23:011950TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061951 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:351952 KeepAliveConnectionResendRequestTest(&write_failure, nullptr);
[email protected]202965992011-12-07 23:04:511953}
1954
bncd16676a2016-07-20 16:23:011955TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061956 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:351957 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251958}
1959
bncd16676a2016-07-20 16:23:011960TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061961 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351962 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251963}
1964
[email protected]d58ceea82014-06-04 10:55:541965// Make sure that on a 408 response (Request Timeout), the request is retried,
1966// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011967TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541968 MockRead read_failure(SYNCHRONOUS,
1969 "HTTP/1.1 408 Request Timeout\r\n"
1970 "Connection: Keep-Alive\r\n"
1971 "Content-Length: 6\r\n\r\n"
1972 "Pickle");
Raul Tambre94493c652019-03-11 17:18:351973 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]d58ceea82014-06-04 10:55:541974}
1975
bncd16676a2016-07-20 16:23:011976TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491977 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:351978 PreconnectErrorResendRequestTest(&write_failure, nullptr, false);
[email protected]a34f61ee2014-03-18 20:59:491979}
1980
bncd16676a2016-07-20 16:23:011981TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491982 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:351983 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491984}
1985
bncd16676a2016-07-20 16:23:011986TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491987 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351988 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]09356c652014-03-25 15:36:101989}
1990
bncd16676a2016-07-20 16:23:011991TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101992 MockRead read_failure(ASYNC, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351993 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]09356c652014-03-25 15:36:101994}
1995
[email protected]d58ceea82014-06-04 10:55:541996// Make sure that on a 408 response (Request Timeout), the request is retried,
1997// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011998TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541999 MockRead read_failure(SYNCHRONOUS,
2000 "HTTP/1.1 408 Request Timeout\r\n"
2001 "Connection: Keep-Alive\r\n"
2002 "Content-Length: 6\r\n\r\n"
2003 "Pickle");
Raul Tambre94493c652019-03-11 17:18:352004 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
2005 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]d58ceea82014-06-04 10:55:542006}
2007
bncd16676a2016-07-20 16:23:012008TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:102009 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:352010 PreconnectErrorResendRequestTest(&write_failure, nullptr, true);
[email protected]09356c652014-03-25 15:36:102011}
2012
bncd16676a2016-07-20 16:23:012013TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:102014 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:352015 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]09356c652014-03-25 15:36:102016}
2017
bncd16676a2016-07-20 16:23:012018TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:102019 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352020 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]09356c652014-03-25 15:36:102021}
2022
bncd16676a2016-07-20 16:23:012023TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:102024 MockRead read_failure(ASYNC, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352025 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:492026}
2027
bncd16676a2016-07-20 16:23:012028TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:422029 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:252030 request.method = "GET";
bncce36dca22015-04-21 22:11:232031 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102032 request.traffic_annotation =
2033 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:252034
danakj1fd259a02016-04-16 03:17:092035 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162036 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272037
[email protected]3d2a59b2008-09-26 19:44:252038 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062039 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:352040 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2041 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062042 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252043 };
Ryan Sleevib8d7ea02018-05-07 20:01:012044 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072045 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:252046
[email protected]49639fa2011-12-20 23:22:412047 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:252048
tfarina42834112016-09-22 13:38:202049 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012050 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:252051
2052 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012053 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:592054
2055 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162056 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592057 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:252058}
2059
2060// What do various browsers do when the server closes a non-keepalive
2061// connection without sending any response header or body?
2062//
2063// IE7: error page
2064// Safari 3.1.2 (Windows): error page
2065// Firefox 3.0.1: blank page
2066// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:422067// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
2068// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:012069TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:252070 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062071 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:352072 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2073 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062074 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252075 };
Ryan Sleevib8d7ea02018-05-07 20:01:012076 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:012077 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:252078}
[email protected]1826a402014-01-08 15:40:482079
[email protected]7a5378b2012-11-04 03:25:172080// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
2081// tests. There was a bug causing HttpNetworkTransaction to hang in the
2082// destructor in such situations.
2083// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:012084TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:172085 HttpRequestInfo request;
2086 request.method = "GET";
bncce36dca22015-04-21 22:11:232087 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102088 request.traffic_annotation =
2089 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172090
danakj1fd259a02016-04-16 03:17:092091 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582092 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192093 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172094
2095 MockRead data_reads[] = {
2096 MockRead("HTTP/1.0 200 OK\r\n"),
2097 MockRead("Connection: keep-alive\r\n"),
2098 MockRead("Content-Length: 100\r\n\r\n"),
2099 MockRead("hello"),
2100 MockRead(SYNCHRONOUS, 0),
2101 };
Ryan Sleevib8d7ea02018-05-07 20:01:012102 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072103 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172104
2105 TestCompletionCallback callback;
2106
tfarina42834112016-09-22 13:38:202107 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012108 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172109
2110 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012111 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172112
Victor Costan9c7302b2018-08-27 16:39:442113 scoped_refptr<IOBufferWithSize> io_buf =
2114 base::MakeRefCounted<IOBufferWithSize>(100);
[email protected]90499482013-06-01 00:39:502115 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172116 if (rv == ERR_IO_PENDING)
2117 rv = callback.WaitForResult();
2118 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:502119 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:012120 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172121
2122 trans.reset();
fdoray92e35a72016-06-10 15:54:552123 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172124 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2125}
2126
bncd16676a2016-07-20 16:23:012127TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:172128 HttpRequestInfo request;
2129 request.method = "GET";
bncce36dca22015-04-21 22:11:232130 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102131 request.traffic_annotation =
2132 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172133
danakj1fd259a02016-04-16 03:17:092134 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582135 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192136 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172137
2138 MockRead data_reads[] = {
2139 MockRead("HTTP/1.0 200 OK\r\n"),
2140 MockRead("Connection: keep-alive\r\n"),
2141 MockRead("Content-Length: 100\r\n\r\n"),
2142 MockRead(SYNCHRONOUS, 0),
2143 };
Ryan Sleevib8d7ea02018-05-07 20:01:012144 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072145 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172146
2147 TestCompletionCallback callback;
2148
tfarina42834112016-09-22 13:38:202149 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012150 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172151
2152 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012153 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172154
Victor Costan9c7302b2018-08-27 16:39:442155 scoped_refptr<IOBufferWithSize> io_buf(
2156 base::MakeRefCounted<IOBufferWithSize>(100));
[email protected]90499482013-06-01 00:39:502157 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172158 if (rv == ERR_IO_PENDING)
2159 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012160 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172161
2162 trans.reset();
fdoray92e35a72016-06-10 15:54:552163 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172164 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2165}
2166
[email protected]0b0bf032010-09-21 18:08:502167// Test that we correctly reuse a keep-alive connection after not explicitly
2168// reading the body.
bncd16676a2016-07-20 16:23:012169TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132170 HttpRequestInfo request;
2171 request.method = "GET";
2172 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102173 request.traffic_annotation =
2174 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132175
vishal.b62985ca92015-04-17 08:45:512176 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072177 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092178 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272179
mmenkecc2298e2015-12-07 18:20:182180 const char* request_data =
2181 "GET / HTTP/1.1\r\n"
2182 "Host: www.foo.com\r\n"
2183 "Connection: keep-alive\r\n\r\n";
2184 MockWrite data_writes[] = {
2185 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2186 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2187 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2188 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2189 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2190 };
2191
[email protected]0b0bf032010-09-21 18:08:502192 // Note that because all these reads happen in the same
2193 // StaticSocketDataProvider, it shows that the same socket is being reused for
2194 // all transactions.
mmenkecc2298e2015-12-07 18:20:182195 MockRead data_reads[] = {
2196 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2197 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2198 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2199 MockRead(ASYNC, 7,
2200 "HTTP/1.1 302 Found\r\n"
2201 "Content-Length: 0\r\n\r\n"),
2202 MockRead(ASYNC, 9,
2203 "HTTP/1.1 302 Found\r\n"
2204 "Content-Length: 5\r\n\r\n"
2205 "hello"),
2206 MockRead(ASYNC, 11,
2207 "HTTP/1.1 301 Moved Permanently\r\n"
2208 "Content-Length: 0\r\n\r\n"),
2209 MockRead(ASYNC, 13,
2210 "HTTP/1.1 301 Moved Permanently\r\n"
2211 "Content-Length: 5\r\n\r\n"
2212 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132213
mmenkecc2298e2015-12-07 18:20:182214 // In the next two rounds, IsConnectedAndIdle returns false, due to
2215 // the set_busy_before_sync_reads(true) call, while the
2216 // HttpNetworkTransaction is being shut down, but the socket is still
2217 // reuseable. See http://crbug.com/544255.
2218 MockRead(ASYNC, 15,
2219 "HTTP/1.1 200 Hunky-Dory\r\n"
2220 "Content-Length: 5\r\n\r\n"),
2221 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132222
mmenkecc2298e2015-12-07 18:20:182223 MockRead(ASYNC, 18,
2224 "HTTP/1.1 200 Hunky-Dory\r\n"
2225 "Content-Length: 5\r\n\r\n"
2226 "he"),
2227 MockRead(SYNCHRONOUS, 19, "llo"),
2228
2229 // The body of the final request is actually read.
2230 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2231 MockRead(ASYNC, 22, "hello"),
2232 };
Ryan Sleevib8d7ea02018-05-07 20:01:012233 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182234 data.set_busy_before_sync_reads(true);
2235 session_deps_.socket_factory->AddSocketDataProvider(&data);
2236
Avi Drissman4365a4782018-12-28 19:26:242237 const int kNumUnreadBodies = base::size(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502238 std::string response_lines[kNumUnreadBodies];
2239
mikecironef22f9812016-10-04 03:40:192240 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182241 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412242 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132243
Jeremy Roman0579ed62017-08-29 15:56:192244 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582245 session.get());
[email protected]fc31d6a42010-06-24 18:05:132246
tfarina42834112016-09-22 13:38:202247 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012248 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132249
[email protected]58e32bb2013-01-21 18:23:252250 LoadTimingInfo load_timing_info;
2251 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2252 if (i == 0) {
2253 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2254 first_socket_log_id = load_timing_info.socket_log_id;
2255 } else {
2256 TestLoadTimingReused(load_timing_info);
2257 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2258 }
2259
[email protected]fc31d6a42010-06-24 18:05:132260 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182261 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132262
mmenkecc2298e2015-12-07 18:20:182263 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502264 response_lines[i] = response->headers->GetStatusLine();
2265
mmenkecc2298e2015-12-07 18:20:182266 // Delete the transaction without reading the response bodies. Then spin
2267 // the message loop, so the response bodies are drained.
2268 trans.reset();
2269 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132270 }
[email protected]0b0bf032010-09-21 18:08:502271
2272 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182273 "HTTP/1.1 204 No Content",
2274 "HTTP/1.1 205 Reset Content",
2275 "HTTP/1.1 304 Not Modified",
2276 "HTTP/1.1 302 Found",
2277 "HTTP/1.1 302 Found",
2278 "HTTP/1.1 301 Moved Permanently",
2279 "HTTP/1.1 301 Moved Permanently",
2280 "HTTP/1.1 200 Hunky-Dory",
2281 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502282 };
2283
Avi Drissman4365a4782018-12-28 19:26:242284 static_assert(kNumUnreadBodies == base::size(kStatusLines),
mostynb91e0da982015-01-20 19:17:272285 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502286
2287 for (int i = 0; i < kNumUnreadBodies; ++i)
2288 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2289
[email protected]49639fa2011-12-20 23:22:412290 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162291 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202292 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012293 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162294 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182295 ASSERT_TRUE(response);
2296 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502297 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2298 std::string response_data;
bnc691fda62016-08-12 00:43:162299 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012300 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502301 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132302}
2303
mmenke5f94fda2016-06-02 20:54:132304// Sockets that receive extra data after a response is complete should not be
2305// reused.
bncd16676a2016-07-20 16:23:012306TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132307 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2308 MockWrite data_writes1[] = {
2309 MockWrite("HEAD / HTTP/1.1\r\n"
2310 "Host: www.borked.com\r\n"
2311 "Connection: keep-alive\r\n\r\n"),
2312 };
2313
2314 MockRead data_reads1[] = {
2315 MockRead("HTTP/1.1 200 OK\r\n"
2316 "Connection: keep-alive\r\n"
2317 "Content-Length: 22\r\n\r\n"
2318 "This server is borked."),
2319 };
2320
2321 MockWrite data_writes2[] = {
2322 MockWrite("GET /foo HTTP/1.1\r\n"
2323 "Host: www.borked.com\r\n"
2324 "Connection: keep-alive\r\n\r\n"),
2325 };
2326
2327 MockRead data_reads2[] = {
2328 MockRead("HTTP/1.1 200 OK\r\n"
2329 "Content-Length: 3\r\n\r\n"
2330 "foo"),
2331 };
Ryan Sleevib8d7ea02018-05-07 20:01:012332 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132333 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012334 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132335 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2336
2337 TestCompletionCallback callback;
2338 HttpRequestInfo request1;
2339 request1.method = "HEAD";
2340 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102341 request1.traffic_annotation =
2342 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132343
bnc87dcefc2017-05-25 12:47:582344 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192345 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202346 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012347 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132348
2349 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2350 ASSERT_TRUE(response1);
2351 ASSERT_TRUE(response1->headers);
2352 EXPECT_EQ(200, response1->headers->response_code());
2353 EXPECT_TRUE(response1->headers->IsKeepAlive());
2354
2355 std::string response_data1;
robpercival214763f2016-07-01 23:27:012356 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132357 EXPECT_EQ("", response_data1);
2358 // Deleting the transaction attempts to release the socket back into the
2359 // socket pool.
2360 trans1.reset();
2361
2362 HttpRequestInfo request2;
2363 request2.method = "GET";
2364 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102365 request2.traffic_annotation =
2366 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132367
bnc87dcefc2017-05-25 12:47:582368 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192369 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202370 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012371 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132372
2373 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2374 ASSERT_TRUE(response2);
2375 ASSERT_TRUE(response2->headers);
2376 EXPECT_EQ(200, response2->headers->response_code());
2377
2378 std::string response_data2;
robpercival214763f2016-07-01 23:27:012379 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132380 EXPECT_EQ("foo", response_data2);
2381}
2382
bncd16676a2016-07-20 16:23:012383TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132384 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2385 MockWrite data_writes1[] = {
2386 MockWrite("GET / HTTP/1.1\r\n"
2387 "Host: www.borked.com\r\n"
2388 "Connection: keep-alive\r\n\r\n"),
2389 };
2390
2391 MockRead data_reads1[] = {
2392 MockRead("HTTP/1.1 200 OK\r\n"
2393 "Connection: keep-alive\r\n"
2394 "Content-Length: 22\r\n\r\n"
2395 "This server is borked."
2396 "Bonus data!"),
2397 };
2398
2399 MockWrite data_writes2[] = {
2400 MockWrite("GET /foo HTTP/1.1\r\n"
2401 "Host: www.borked.com\r\n"
2402 "Connection: keep-alive\r\n\r\n"),
2403 };
2404
2405 MockRead data_reads2[] = {
2406 MockRead("HTTP/1.1 200 OK\r\n"
2407 "Content-Length: 3\r\n\r\n"
2408 "foo"),
2409 };
Ryan Sleevib8d7ea02018-05-07 20:01:012410 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132411 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012412 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132413 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2414
2415 TestCompletionCallback callback;
2416 HttpRequestInfo request1;
2417 request1.method = "GET";
2418 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102419 request1.traffic_annotation =
2420 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132421
bnc87dcefc2017-05-25 12:47:582422 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192423 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202424 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012425 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132426
2427 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2428 ASSERT_TRUE(response1);
2429 ASSERT_TRUE(response1->headers);
2430 EXPECT_EQ(200, response1->headers->response_code());
2431 EXPECT_TRUE(response1->headers->IsKeepAlive());
2432
2433 std::string response_data1;
robpercival214763f2016-07-01 23:27:012434 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132435 EXPECT_EQ("This server is borked.", response_data1);
2436 // Deleting the transaction attempts to release the socket back into the
2437 // socket pool.
2438 trans1.reset();
2439
2440 HttpRequestInfo request2;
2441 request2.method = "GET";
2442 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102443 request2.traffic_annotation =
2444 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132445
bnc87dcefc2017-05-25 12:47:582446 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192447 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202448 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012449 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132450
2451 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2452 ASSERT_TRUE(response2);
2453 ASSERT_TRUE(response2->headers);
2454 EXPECT_EQ(200, response2->headers->response_code());
2455
2456 std::string response_data2;
robpercival214763f2016-07-01 23:27:012457 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132458 EXPECT_EQ("foo", response_data2);
2459}
2460
bncd16676a2016-07-20 16:23:012461TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132462 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2463 MockWrite data_writes1[] = {
2464 MockWrite("GET / HTTP/1.1\r\n"
2465 "Host: www.borked.com\r\n"
2466 "Connection: keep-alive\r\n\r\n"),
2467 };
2468
2469 MockRead data_reads1[] = {
2470 MockRead("HTTP/1.1 200 OK\r\n"
2471 "Connection: keep-alive\r\n"
2472 "Transfer-Encoding: chunked\r\n\r\n"),
2473 MockRead("16\r\nThis server is borked.\r\n"),
2474 MockRead("0\r\n\r\nBonus data!"),
2475 };
2476
2477 MockWrite data_writes2[] = {
2478 MockWrite("GET /foo HTTP/1.1\r\n"
2479 "Host: www.borked.com\r\n"
2480 "Connection: keep-alive\r\n\r\n"),
2481 };
2482
2483 MockRead data_reads2[] = {
2484 MockRead("HTTP/1.1 200 OK\r\n"
2485 "Content-Length: 3\r\n\r\n"
2486 "foo"),
2487 };
Ryan Sleevib8d7ea02018-05-07 20:01:012488 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132489 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012490 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132491 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2492
2493 TestCompletionCallback callback;
2494 HttpRequestInfo request1;
2495 request1.method = "GET";
2496 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102497 request1.traffic_annotation =
2498 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132499
bnc87dcefc2017-05-25 12:47:582500 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192501 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202502 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012503 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132504
2505 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2506 ASSERT_TRUE(response1);
2507 ASSERT_TRUE(response1->headers);
2508 EXPECT_EQ(200, response1->headers->response_code());
2509 EXPECT_TRUE(response1->headers->IsKeepAlive());
2510
2511 std::string response_data1;
robpercival214763f2016-07-01 23:27:012512 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132513 EXPECT_EQ("This server is borked.", response_data1);
2514 // Deleting the transaction attempts to release the socket back into the
2515 // socket pool.
2516 trans1.reset();
2517
2518 HttpRequestInfo request2;
2519 request2.method = "GET";
2520 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102521 request2.traffic_annotation =
2522 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132523
bnc87dcefc2017-05-25 12:47:582524 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192525 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202526 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012527 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132528
2529 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2530 ASSERT_TRUE(response2);
2531 ASSERT_TRUE(response2->headers);
2532 EXPECT_EQ(200, response2->headers->response_code());
2533
2534 std::string response_data2;
robpercival214763f2016-07-01 23:27:012535 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132536 EXPECT_EQ("foo", response_data2);
2537}
2538
2539// This is a little different from the others - it tests the case that the
2540// HttpStreamParser doesn't know if there's extra data on a socket or not when
2541// the HttpNetworkTransaction is torn down, because the response body hasn't
2542// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012543TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132544 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2545 MockWrite data_writes1[] = {
2546 MockWrite("GET / HTTP/1.1\r\n"
2547 "Host: www.borked.com\r\n"
2548 "Connection: keep-alive\r\n\r\n"),
2549 };
2550
2551 MockRead data_reads1[] = {
2552 MockRead("HTTP/1.1 200 OK\r\n"
2553 "Connection: keep-alive\r\n"
2554 "Transfer-Encoding: chunked\r\n\r\n"),
2555 MockRead("16\r\nThis server is borked.\r\n"),
2556 MockRead("0\r\n\r\nBonus data!"),
2557 };
Ryan Sleevib8d7ea02018-05-07 20:01:012558 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132559 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2560
2561 TestCompletionCallback callback;
2562 HttpRequestInfo request1;
2563 request1.method = "GET";
2564 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102565 request1.traffic_annotation =
2566 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132567
bnc87dcefc2017-05-25 12:47:582568 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192569 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582570 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012571 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132572
bnc87dcefc2017-05-25 12:47:582573 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132574 ASSERT_TRUE(response1);
2575 ASSERT_TRUE(response1->headers);
2576 EXPECT_EQ(200, response1->headers->response_code());
2577 EXPECT_TRUE(response1->headers->IsKeepAlive());
2578
2579 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2580 // response body.
bnc87dcefc2017-05-25 12:47:582581 trans.reset();
mmenke5f94fda2016-06-02 20:54:132582
2583 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2584 // socket can't be reused, rather than returning it to the socket pool.
2585 base::RunLoop().RunUntilIdle();
2586
2587 // There should be no idle sockets in the pool.
2588 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2589}
2590
[email protected]038e9a32008-10-08 22:40:162591// Test the request-challenge-retry sequence for basic auth.
2592// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012593TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422594 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162595 request.method = "GET";
bncce36dca22015-04-21 22:11:232596 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102597 request.traffic_annotation =
2598 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162599
vishal.b62985ca92015-04-17 08:45:512600 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072601 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272604
[email protected]f9ee6b52008-11-08 06:46:232605 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232606 MockWrite(
2607 "GET / HTTP/1.1\r\n"
2608 "Host: www.example.org\r\n"
2609 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232610 };
2611
[email protected]038e9a32008-10-08 22:40:162612 MockRead data_reads1[] = {
2613 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2614 // Give a couple authenticate options (only the middle one is actually
2615 // supported).
[email protected]22927ad2009-09-21 19:56:192616 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162617 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2618 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2619 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2620 // Large content-length -- won't matter, as connection will be reset.
2621 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062622 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162623 };
2624
2625 // After calling trans->RestartWithAuth(), this is the request we should
2626 // be issuing -- the final header line contains the credentials.
2627 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232628 MockWrite(
2629 "GET / HTTP/1.1\r\n"
2630 "Host: www.example.org\r\n"
2631 "Connection: keep-alive\r\n"
2632 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162633 };
2634
2635 // Lastly, the server responds with the actual content.
2636 MockRead data_reads2[] = {
2637 MockRead("HTTP/1.0 200 OK\r\n"),
2638 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2639 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062640 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162641 };
2642
Ryan Sleevib8d7ea02018-05-07 20:01:012643 StaticSocketDataProvider data1(data_reads1, data_writes1);
2644 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072645 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2646 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162647
[email protected]49639fa2011-12-20 23:22:412648 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162649
tfarina42834112016-09-22 13:38:202650 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162652
2653 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012654 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162655
[email protected]58e32bb2013-01-21 18:23:252656 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162657 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252658 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2659
Ryan Sleevib8d7ea02018-05-07 20:01:012660 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162661 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012662 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162663 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192664
bnc691fda62016-08-12 00:43:162665 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522666 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042667 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162668
[email protected]49639fa2011-12-20 23:22:412669 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162670
bnc691fda62016-08-12 00:43:162671 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162673
2674 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012675 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162676
[email protected]58e32bb2013-01-21 18:23:252677 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162678 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252679 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2680 // The load timing after restart should have a new socket ID, and times after
2681 // those of the first load timing.
2682 EXPECT_LE(load_timing_info1.receive_headers_end,
2683 load_timing_info2.connect_timing.connect_start);
2684 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2685
Ryan Sleevib8d7ea02018-05-07 20:01:012686 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162687 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012688 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162689 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192690
bnc691fda62016-08-12 00:43:162691 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522692 ASSERT_TRUE(response);
2693 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162694 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162695}
2696
ttuttled9dbc652015-09-29 20:00:592697// Test the request-challenge-retry sequence for basic auth.
2698// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012699TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592700 HttpRequestInfo request;
2701 request.method = "GET";
2702 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102703 request.traffic_annotation =
2704 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592705
2706 TestNetLog log;
2707 MockHostResolver* resolver = new MockHostResolver();
2708 session_deps_.net_log = &log;
2709 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092710 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162711 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592712
2713 resolver->rules()->ClearRules();
2714 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2715
2716 MockWrite data_writes1[] = {
2717 MockWrite("GET / HTTP/1.1\r\n"
2718 "Host: www.example.org\r\n"
2719 "Connection: keep-alive\r\n\r\n"),
2720 };
2721
2722 MockRead data_reads1[] = {
2723 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2724 // Give a couple authenticate options (only the middle one is actually
2725 // supported).
2726 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2727 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2728 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2729 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2730 // Large content-length -- won't matter, as connection will be reset.
2731 MockRead("Content-Length: 10000\r\n\r\n"),
2732 MockRead(SYNCHRONOUS, ERR_FAILED),
2733 };
2734
2735 // After calling trans->RestartWithAuth(), this is the request we should
2736 // be issuing -- the final header line contains the credentials.
2737 MockWrite data_writes2[] = {
2738 MockWrite("GET / HTTP/1.1\r\n"
2739 "Host: www.example.org\r\n"
2740 "Connection: keep-alive\r\n"
2741 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2742 };
2743
2744 // Lastly, the server responds with the actual content.
2745 MockRead data_reads2[] = {
2746 MockRead("HTTP/1.0 200 OK\r\n"),
2747 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2748 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2749 };
2750
Ryan Sleevib8d7ea02018-05-07 20:01:012751 StaticSocketDataProvider data1(data_reads1, data_writes1);
2752 StaticSocketDataProvider data2(data_reads2, data_writes2);
ttuttled9dbc652015-09-29 20:00:592753 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2754 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2755
2756 TestCompletionCallback callback1;
2757
bnc691fda62016-08-12 00:43:162758 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202759 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592760
2761 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162762 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592763 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2764
Ryan Sleevib8d7ea02018-05-07 20:01:012765 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162766 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012767 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162768 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592769
bnc691fda62016-08-12 00:43:162770 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592771 ASSERT_TRUE(response);
2772 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2773
2774 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162775 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592776 ASSERT_FALSE(endpoint.address().empty());
2777 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2778
2779 resolver->rules()->ClearRules();
2780 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2781
2782 TestCompletionCallback callback2;
2783
bnc691fda62016-08-12 00:43:162784 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592785 AuthCredentials(kFoo, kBar), callback2.callback())));
2786
2787 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162788 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592789 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2790 // The load timing after restart should have a new socket ID, and times after
2791 // those of the first load timing.
2792 EXPECT_LE(load_timing_info1.receive_headers_end,
2793 load_timing_info2.connect_timing.connect_start);
2794 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2795
Ryan Sleevib8d7ea02018-05-07 20:01:012796 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162797 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012798 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162799 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592800
bnc691fda62016-08-12 00:43:162801 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592802 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522803 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592804 EXPECT_EQ(100, response->headers->GetContentLength());
2805
bnc691fda62016-08-12 00:43:162806 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592807 ASSERT_FALSE(endpoint.address().empty());
2808 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2809}
2810
David Benjamin83ddfb32018-03-30 01:07:522811// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2812// will eventually give up.
2813TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2814 HttpRequestInfo request;
2815 request.method = "GET";
2816 request.url = GURL("http://www.example.org/");
2817 request.traffic_annotation =
2818 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2819
2820 TestNetLog log;
2821 session_deps_.net_log = &log;
2822 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2823 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2824
2825 MockWrite data_writes[] = {
2826 MockWrite("GET / HTTP/1.1\r\n"
2827 "Host: www.example.org\r\n"
2828 "Connection: keep-alive\r\n\r\n"),
2829 };
2830
2831 MockRead data_reads[] = {
2832 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2833 // Give a couple authenticate options (only the middle one is actually
2834 // supported).
2835 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2836 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2837 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2838 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2839 // Large content-length -- won't matter, as connection will be reset.
2840 MockRead("Content-Length: 10000\r\n\r\n"),
2841 MockRead(SYNCHRONOUS, ERR_FAILED),
2842 };
2843
2844 // After calling trans->RestartWithAuth(), this is the request we should
2845 // be issuing -- the final header line contains the credentials.
2846 MockWrite data_writes_restart[] = {
2847 MockWrite("GET / HTTP/1.1\r\n"
2848 "Host: www.example.org\r\n"
2849 "Connection: keep-alive\r\n"
2850 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2851 };
2852
Ryan Sleevib8d7ea02018-05-07 20:01:012853 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin83ddfb32018-03-30 01:07:522854 session_deps_.socket_factory->AddSocketDataProvider(&data);
2855
2856 TestCompletionCallback callback;
2857 int rv = callback.GetResult(
2858 trans.Start(&request, callback.callback(), NetLogWithSource()));
2859
2860 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2861 for (int i = 0; i < 32; i++) {
2862 // Check the previous response was a 401.
2863 EXPECT_THAT(rv, IsOk());
2864 const HttpResponseInfo* response = trans.GetResponseInfo();
2865 ASSERT_TRUE(response);
2866 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2867
2868 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:012869 data_reads, data_writes_restart));
David Benjamin83ddfb32018-03-30 01:07:522870 session_deps_.socket_factory->AddSocketDataProvider(
2871 data_restarts.back().get());
2872 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2873 callback.callback()));
2874 }
2875
2876 // After too many tries, the transaction should have given up.
2877 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2878}
2879
bncd16676a2016-07-20 16:23:012880TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462881 HttpRequestInfo request;
2882 request.method = "GET";
bncce36dca22015-04-21 22:11:232883 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292884 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:102885 request.traffic_annotation =
2886 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462887
danakj1fd259a02016-04-16 03:17:092888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162889 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272890
[email protected]861fcd52009-08-26 02:33:462891 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232892 MockWrite(
2893 "GET / HTTP/1.1\r\n"
2894 "Host: www.example.org\r\n"
2895 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462896 };
2897
2898 MockRead data_reads[] = {
2899 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2900 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2901 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2902 // Large content-length -- won't matter, as connection will be reset.
2903 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062904 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462905 };
2906
Ryan Sleevib8d7ea02018-05-07 20:01:012907 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:072908 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412909 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462910
tfarina42834112016-09-22 13:38:202911 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012912 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462913
2914 rv = callback.WaitForResult();
2915 EXPECT_EQ(0, rv);
2916
Ryan Sleevib8d7ea02018-05-07 20:01:012917 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162918 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012919 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162920 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192921
bnc691fda62016-08-12 00:43:162922 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522923 ASSERT_TRUE(response);
2924 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462925}
2926
[email protected]2d2697f92009-02-18 21:00:322927// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2928// connection.
bncd16676a2016-07-20 16:23:012929TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182930 // On the second pass, the body read of the auth challenge is synchronous, so
2931 // IsConnectedAndIdle returns false. The socket should still be drained and
2932 // reused. See http://crbug.com/544255.
2933 for (int i = 0; i < 2; ++i) {
2934 HttpRequestInfo request;
2935 request.method = "GET";
2936 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102937 request.traffic_annotation =
2938 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322939
mmenkecc2298e2015-12-07 18:20:182940 TestNetLog log;
2941 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092942 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272943
mmenkecc2298e2015-12-07 18:20:182944 MockWrite data_writes[] = {
2945 MockWrite(ASYNC, 0,
2946 "GET / HTTP/1.1\r\n"
2947 "Host: www.example.org\r\n"
2948 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322949
bnc691fda62016-08-12 00:43:162950 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182951 // be issuing -- the final header line contains the credentials.
2952 MockWrite(ASYNC, 6,
2953 "GET / HTTP/1.1\r\n"
2954 "Host: www.example.org\r\n"
2955 "Connection: keep-alive\r\n"
2956 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2957 };
[email protected]2d2697f92009-02-18 21:00:322958
mmenkecc2298e2015-12-07 18:20:182959 MockRead data_reads[] = {
2960 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2961 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2962 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2963 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2964 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322965
mmenkecc2298e2015-12-07 18:20:182966 // Lastly, the server responds with the actual content.
2967 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2968 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2969 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2970 MockRead(ASYNC, 10, "Hello"),
2971 };
[email protected]2d2697f92009-02-18 21:00:322972
Ryan Sleevib8d7ea02018-05-07 20:01:012973 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182974 data.set_busy_before_sync_reads(true);
2975 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462976
mmenkecc2298e2015-12-07 18:20:182977 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322978
bnc691fda62016-08-12 00:43:162979 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202980 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012981 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322982
mmenkecc2298e2015-12-07 18:20:182983 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162984 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182985 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322986
bnc691fda62016-08-12 00:43:162987 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182988 ASSERT_TRUE(response);
2989 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322990
mmenkecc2298e2015-12-07 18:20:182991 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252992
bnc691fda62016-08-12 00:43:162993 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2994 callback2.callback());
robpercival214763f2016-07-01 23:27:012995 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322996
mmenkecc2298e2015-12-07 18:20:182997 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162998 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182999 TestLoadTimingReused(load_timing_info2);
3000 // The load timing after restart should have the same socket ID, and times
3001 // those of the first load timing.
3002 EXPECT_LE(load_timing_info1.receive_headers_end,
3003 load_timing_info2.send_start);
3004 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:323005
bnc691fda62016-08-12 00:43:163006 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:183007 ASSERT_TRUE(response);
3008 EXPECT_FALSE(response->auth_challenge);
3009 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323010
mmenkecc2298e2015-12-07 18:20:183011 std::string response_data;
bnc691fda62016-08-12 00:43:163012 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:323013
Ryan Sleevib8d7ea02018-05-07 20:01:013014 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:163015 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:013016 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:163017 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:183018 }
[email protected]2d2697f92009-02-18 21:00:323019}
3020
3021// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3022// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:013023TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:423024 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323025 request.method = "GET";
bncce36dca22015-04-21 22:11:233026 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103027 request.traffic_annotation =
3028 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323029
danakj1fd259a02016-04-16 03:17:093030 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273031
[email protected]2d2697f92009-02-18 21:00:323032 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163033 MockWrite("GET / HTTP/1.1\r\n"
3034 "Host: www.example.org\r\n"
3035 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323036
bnc691fda62016-08-12 00:43:163037 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233038 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163039 MockWrite("GET / HTTP/1.1\r\n"
3040 "Host: www.example.org\r\n"
3041 "Connection: keep-alive\r\n"
3042 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323043 };
3044
[email protected]2d2697f92009-02-18 21:00:323045 MockRead data_reads1[] = {
3046 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3047 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:313048 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:323049
3050 // Lastly, the server responds with the actual content.
3051 MockRead("HTTP/1.1 200 OK\r\n"),
3052 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503053 MockRead("Content-Length: 5\r\n\r\n"),
3054 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323055 };
3056
[email protected]2d0a4f92011-05-05 16:38:463057 // An incorrect reconnect would cause this to be read.
3058 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063059 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463060 };
3061
Ryan Sleevib8d7ea02018-05-07 20:01:013062 StaticSocketDataProvider data1(data_reads1, data_writes1);
3063 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073064 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3065 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323066
[email protected]49639fa2011-12-20 23:22:413067 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323068
bnc691fda62016-08-12 00:43:163069 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203070 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323072
3073 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013074 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323075
bnc691fda62016-08-12 00:43:163076 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523077 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043078 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323079
[email protected]49639fa2011-12-20 23:22:413080 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323081
bnc691fda62016-08-12 00:43:163082 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013083 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323084
3085 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013086 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323087
bnc691fda62016-08-12 00:43:163088 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523089 ASSERT_TRUE(response);
3090 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503091 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323092}
3093
3094// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3095// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:013096TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:423097 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323098 request.method = "GET";
bncce36dca22015-04-21 22:11:233099 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103100 request.traffic_annotation =
3101 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323102
danakj1fd259a02016-04-16 03:17:093103 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273104
[email protected]2d2697f92009-02-18 21:00:323105 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163106 MockWrite("GET / HTTP/1.1\r\n"
3107 "Host: www.example.org\r\n"
3108 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323109
bnc691fda62016-08-12 00:43:163110 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233111 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163112 MockWrite("GET / HTTP/1.1\r\n"
3113 "Host: www.example.org\r\n"
3114 "Connection: keep-alive\r\n"
3115 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323116 };
3117
3118 // Respond with 5 kb of response body.
3119 std::string large_body_string("Unauthorized");
3120 large_body_string.append(5 * 1024, ' ');
3121 large_body_string.append("\r\n");
3122
3123 MockRead data_reads1[] = {
3124 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3125 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3126 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3127 // 5134 = 12 + 5 * 1024 + 2
3128 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063129 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:323130
3131 // Lastly, the server responds with the actual content.
3132 MockRead("HTTP/1.1 200 OK\r\n"),
3133 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503134 MockRead("Content-Length: 5\r\n\r\n"),
3135 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323136 };
3137
[email protected]2d0a4f92011-05-05 16:38:463138 // An incorrect reconnect would cause this to be read.
3139 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063140 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463141 };
3142
Ryan Sleevib8d7ea02018-05-07 20:01:013143 StaticSocketDataProvider data1(data_reads1, data_writes1);
3144 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073145 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3146 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323147
[email protected]49639fa2011-12-20 23:22:413148 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323149
bnc691fda62016-08-12 00:43:163150 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203151 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013152 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323153
3154 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013155 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323156
bnc691fda62016-08-12 00:43:163157 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523158 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043159 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323160
[email protected]49639fa2011-12-20 23:22:413161 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323162
bnc691fda62016-08-12 00:43:163163 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013164 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323165
3166 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013167 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323168
bnc691fda62016-08-12 00:43:163169 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523170 ASSERT_TRUE(response);
3171 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503172 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323173}
3174
3175// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:313176// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:013177TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:313178 HttpRequestInfo request;
3179 request.method = "GET";
bncce36dca22015-04-21 22:11:233180 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103181 request.traffic_annotation =
3182 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313183
danakj1fd259a02016-04-16 03:17:093184 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273185
[email protected]11203f012009-11-12 23:02:313186 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233187 MockWrite(
3188 "GET / HTTP/1.1\r\n"
3189 "Host: www.example.org\r\n"
3190 "Connection: keep-alive\r\n\r\n"),
3191 // This simulates the seemingly successful write to a closed connection
3192 // if the bug is not fixed.
3193 MockWrite(
3194 "GET / HTTP/1.1\r\n"
3195 "Host: www.example.org\r\n"
3196 "Connection: keep-alive\r\n"
3197 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313198 };
3199
3200 MockRead data_reads1[] = {
3201 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3202 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3203 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3204 MockRead("Content-Length: 14\r\n\r\n"),
3205 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063206 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313207 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063208 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313209 };
3210
bnc691fda62016-08-12 00:43:163211 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313212 // be issuing -- the final header line contains the credentials.
3213 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233214 MockWrite(
3215 "GET / HTTP/1.1\r\n"
3216 "Host: www.example.org\r\n"
3217 "Connection: keep-alive\r\n"
3218 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313219 };
3220
3221 // Lastly, the server responds with the actual content.
3222 MockRead data_reads2[] = {
3223 MockRead("HTTP/1.1 200 OK\r\n"),
3224 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503225 MockRead("Content-Length: 5\r\n\r\n"),
3226 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313227 };
3228
Ryan Sleevib8d7ea02018-05-07 20:01:013229 StaticSocketDataProvider data1(data_reads1, data_writes1);
3230 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:073231 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3232 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313233
[email protected]49639fa2011-12-20 23:22:413234 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313235
bnc691fda62016-08-12 00:43:163236 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203237 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013238 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313239
3240 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013241 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313242
bnc691fda62016-08-12 00:43:163243 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523244 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043245 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313246
[email protected]49639fa2011-12-20 23:22:413247 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313248
bnc691fda62016-08-12 00:43:163249 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013250 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313251
3252 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013253 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313254
bnc691fda62016-08-12 00:43:163255 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523256 ASSERT_TRUE(response);
3257 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503258 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313259}
3260
[email protected]394816e92010-08-03 07:38:593261// Test the request-challenge-retry sequence for basic auth, over a connection
3262// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013263TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013264 HttpRequestInfo request;
3265 request.method = "GET";
bncce36dca22015-04-21 22:11:233266 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013267 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293268 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103269 request.traffic_annotation =
3270 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013271
3272 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593273 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493274 ProxyResolutionService::CreateFixedFromPacResult(
3275 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513276 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013277 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093278 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013279
3280 // Since we have proxy, should try to establish tunnel.
3281 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543282 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173283 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543284 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013285 };
3286
mmenkee71e15332015-10-07 16:39:543287 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013288 // connection.
3289 MockRead data_reads1[] = {
3290 // No credentials.
3291 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3292 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543293 };
ttuttle34f63b52015-03-05 04:33:013294
mmenkee71e15332015-10-07 16:39:543295 // Since the first connection couldn't be reused, need to establish another
3296 // once given credentials.
3297 MockWrite data_writes2[] = {
3298 // After calling trans->RestartWithAuth(), this is the request we should
3299 // be issuing -- the final header line contains the credentials.
3300 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173301 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543302 "Proxy-Connection: keep-alive\r\n"
3303 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3304
3305 MockWrite("GET / HTTP/1.1\r\n"
3306 "Host: www.example.org\r\n"
3307 "Connection: keep-alive\r\n\r\n"),
3308 };
3309
3310 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013311 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3312
3313 MockRead("HTTP/1.1 200 OK\r\n"),
3314 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3315 MockRead("Content-Length: 5\r\n\r\n"),
3316 MockRead(SYNCHRONOUS, "hello"),
3317 };
3318
Ryan Sleevib8d7ea02018-05-07 20:01:013319 StaticSocketDataProvider data1(data_reads1, data_writes1);
ttuttle34f63b52015-03-05 04:33:013320 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013321 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543322 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013323 SSLSocketDataProvider ssl(ASYNC, OK);
3324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3325
3326 TestCompletionCallback callback1;
3327
bnc87dcefc2017-05-25 12:47:583328 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193329 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013330
3331 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013332 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013333
3334 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013335 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463336 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013337 log.GetEntries(&entries);
3338 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003339 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3340 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013341 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003342 entries, pos,
3343 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3344 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013345
3346 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523347 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013348 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523349 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013350 EXPECT_EQ(407, response->headers->response_code());
3351 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3352 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3353
3354 LoadTimingInfo load_timing_info;
3355 // CONNECT requests and responses are handled at the connect job level, so
3356 // the transaction does not yet have a connection.
3357 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3358
3359 TestCompletionCallback callback2;
3360
3361 rv =
3362 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013363 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013364
3365 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013366 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013367
3368 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523369 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013370
3371 EXPECT_TRUE(response->headers->IsKeepAlive());
3372 EXPECT_EQ(200, response->headers->response_code());
3373 EXPECT_EQ(5, response->headers->GetContentLength());
3374 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3375
3376 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523377 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013378
3379 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3380 TestLoadTimingNotReusedWithPac(load_timing_info,
3381 CONNECT_TIMING_HAS_SSL_TIMES);
3382
3383 trans.reset();
3384 session->CloseAllConnections();
3385}
3386
3387// Test the request-challenge-retry sequence for basic auth, over a connection
3388// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013389TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593390 HttpRequestInfo request;
3391 request.method = "GET";
bncce36dca22015-04-21 22:11:233392 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593393 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293394 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103395 request.traffic_annotation =
3396 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593397
[email protected]cb9bf6ca2011-01-28 13:15:273398 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593399 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493400 ProxyResolutionService::CreateFixedFromPacResult(
3401 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513402 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073403 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093404 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273405
[email protected]394816e92010-08-03 07:38:593406 // Since we have proxy, should try to establish tunnel.
3407 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543408 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173409 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543410 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113411 };
3412
mmenkee71e15332015-10-07 16:39:543413 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083414 // connection.
3415 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543416 // No credentials.
3417 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3418 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3419 MockRead("Proxy-Connection: close\r\n\r\n"),
3420 };
mmenkee0b5c882015-08-26 20:29:113421
mmenkee71e15332015-10-07 16:39:543422 MockWrite data_writes2[] = {
3423 // After calling trans->RestartWithAuth(), this is the request we should
3424 // be issuing -- the final header line contains the credentials.
3425 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173426 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543427 "Proxy-Connection: keep-alive\r\n"
3428 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083429
mmenkee71e15332015-10-07 16:39:543430 MockWrite("GET / HTTP/1.1\r\n"
3431 "Host: www.example.org\r\n"
3432 "Connection: keep-alive\r\n\r\n"),
3433 };
3434
3435 MockRead data_reads2[] = {
3436 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3437
3438 MockRead("HTTP/1.1 200 OK\r\n"),
3439 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3440 MockRead("Content-Length: 5\r\n\r\n"),
3441 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593442 };
3443
Ryan Sleevib8d7ea02018-05-07 20:01:013444 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073445 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013446 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543447 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063448 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073449 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593450
[email protected]49639fa2011-12-20 23:22:413451 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593452
bnc87dcefc2017-05-25 12:47:583453 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193454 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503455
[email protected]49639fa2011-12-20 23:22:413456 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013457 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593458
3459 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013460 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463461 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403462 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593463 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003464 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3465 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593466 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403467 entries, pos,
mikecirone8b85c432016-09-08 19:11:003468 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3469 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593470
3471 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523472 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013473 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523474 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593475 EXPECT_EQ(407, response->headers->response_code());
3476 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043477 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593478
[email protected]029c83b62013-01-24 05:28:203479 LoadTimingInfo load_timing_info;
3480 // CONNECT requests and responses are handled at the connect job level, so
3481 // the transaction does not yet have a connection.
3482 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3483
[email protected]49639fa2011-12-20 23:22:413484 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593485
[email protected]49639fa2011-12-20 23:22:413486 rv = trans->RestartWithAuth(
3487 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013488 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593489
3490 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013491 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593492
3493 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523494 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593495
3496 EXPECT_TRUE(response->headers->IsKeepAlive());
3497 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503498 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593499 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3500
3501 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523502 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503503
[email protected]029c83b62013-01-24 05:28:203504 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3505 TestLoadTimingNotReusedWithPac(load_timing_info,
3506 CONNECT_TIMING_HAS_SSL_TIMES);
3507
[email protected]0b0bf032010-09-21 18:08:503508 trans.reset();
[email protected]102e27c2011-02-23 01:01:313509 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593510}
3511
[email protected]11203f012009-11-12 23:02:313512// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013513// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013514TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233515 // On the second pass, the body read of the auth challenge is synchronous, so
3516 // IsConnectedAndIdle returns false. The socket should still be drained and
3517 // reused. See http://crbug.com/544255.
3518 for (int i = 0; i < 2; ++i) {
3519 HttpRequestInfo request;
3520 request.method = "GET";
3521 request.url = GURL("https://www.example.org/");
3522 // Ensure that proxy authentication is attempted even
3523 // when the no authentication data flag is set.
3524 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103525 request.traffic_annotation =
3526 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013527
mmenked39192ee2015-12-09 00:57:233528 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593529 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493530 ProxyResolutionService::CreateFixed("myproxy:70",
3531 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233532 BoundTestNetLog log;
3533 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093534 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013535
bnc691fda62016-08-12 00:43:163536 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013537
mmenked39192ee2015-12-09 00:57:233538 // Since we have proxy, should try to establish tunnel.
3539 MockWrite data_writes1[] = {
3540 MockWrite(ASYNC, 0,
3541 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3542 "Host: www.example.org:443\r\n"
3543 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013544
bnc691fda62016-08-12 00:43:163545 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233546 // be issuing -- the final header line contains the credentials.
3547 MockWrite(ASYNC, 3,
3548 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3549 "Host: www.example.org:443\r\n"
3550 "Proxy-Connection: keep-alive\r\n"
3551 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3552 };
ttuttle34f63b52015-03-05 04:33:013553
mmenked39192ee2015-12-09 00:57:233554 // The proxy responds to the connect with a 407, using a persistent
3555 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3556 MockRead data_reads1[] = {
3557 // No credentials.
3558 MockRead(ASYNC, 1,
3559 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3560 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3561 "Proxy-Connection: keep-alive\r\n"
3562 "Content-Length: 10\r\n\r\n"),
3563 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013564
mmenked39192ee2015-12-09 00:57:233565 // Wrong credentials (wrong password).
3566 MockRead(ASYNC, 4,
3567 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3568 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3569 "Proxy-Connection: keep-alive\r\n"
3570 "Content-Length: 10\r\n\r\n"),
3571 // No response body because the test stops reading here.
3572 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3573 };
ttuttle34f63b52015-03-05 04:33:013574
Ryan Sleevib8d7ea02018-05-07 20:01:013575 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233576 data1.set_busy_before_sync_reads(true);
3577 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013578
mmenked39192ee2015-12-09 00:57:233579 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013580
bnc691fda62016-08-12 00:43:163581 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013582 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013583
mmenked39192ee2015-12-09 00:57:233584 TestNetLogEntry::List entries;
3585 log.GetEntries(&entries);
3586 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003587 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3588 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233589 ExpectLogContainsSomewhere(
3590 entries, pos,
mikecirone8b85c432016-09-08 19:11:003591 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3592 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013593
bnc691fda62016-08-12 00:43:163594 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233595 ASSERT_TRUE(response);
3596 ASSERT_TRUE(response->headers);
3597 EXPECT_TRUE(response->headers->IsKeepAlive());
3598 EXPECT_EQ(407, response->headers->response_code());
3599 EXPECT_EQ(10, response->headers->GetContentLength());
3600 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3601 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013602
mmenked39192ee2015-12-09 00:57:233603 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013604
mmenked39192ee2015-12-09 00:57:233605 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163606 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3607 callback2.callback());
robpercival214763f2016-07-01 23:27:013608 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013609
bnc691fda62016-08-12 00:43:163610 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233611 ASSERT_TRUE(response);
3612 ASSERT_TRUE(response->headers);
3613 EXPECT_TRUE(response->headers->IsKeepAlive());
3614 EXPECT_EQ(407, response->headers->response_code());
3615 EXPECT_EQ(10, response->headers->GetContentLength());
3616 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3617 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013618
mmenked39192ee2015-12-09 00:57:233619 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3620 // out of scope.
3621 session->CloseAllConnections();
3622 }
ttuttle34f63b52015-03-05 04:33:013623}
3624
3625// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3626// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013627TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233628 // On the second pass, the body read of the auth challenge is synchronous, so
3629 // IsConnectedAndIdle returns false. The socket should still be drained and
3630 // reused. See http://crbug.com/544255.
3631 for (int i = 0; i < 2; ++i) {
3632 HttpRequestInfo request;
3633 request.method = "GET";
3634 request.url = GURL("https://www.example.org/");
3635 // Ensure that proxy authentication is attempted even
3636 // when the no authentication data flag is set.
3637 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103638 request.traffic_annotation =
3639 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233640
3641 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593642 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493643 ProxyResolutionService::CreateFixed("myproxy:70",
3644 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233645 BoundTestNetLog log;
3646 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093647 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233648
bnc691fda62016-08-12 00:43:163649 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233650
3651 // Since we have proxy, should try to establish tunnel.
3652 MockWrite data_writes1[] = {
3653 MockWrite(ASYNC, 0,
3654 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3655 "Host: www.example.org:443\r\n"
3656 "Proxy-Connection: keep-alive\r\n\r\n"),
3657
bnc691fda62016-08-12 00:43:163658 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233659 // be issuing -- the final header line contains the credentials.
3660 MockWrite(ASYNC, 3,
3661 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3662 "Host: www.example.org:443\r\n"
3663 "Proxy-Connection: keep-alive\r\n"
3664 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3665 };
3666
3667 // The proxy responds to the connect with a 407, using a persistent
3668 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3669 MockRead data_reads1[] = {
3670 // No credentials.
3671 MockRead(ASYNC, 1,
3672 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3673 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3674 "Content-Length: 10\r\n\r\n"),
3675 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3676
3677 // Wrong credentials (wrong password).
3678 MockRead(ASYNC, 4,
3679 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3680 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3681 "Content-Length: 10\r\n\r\n"),
3682 // No response body because the test stops reading here.
3683 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3684 };
3685
Ryan Sleevib8d7ea02018-05-07 20:01:013686 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233687 data1.set_busy_before_sync_reads(true);
3688 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3689
3690 TestCompletionCallback callback1;
3691
bnc691fda62016-08-12 00:43:163692 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013693 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233694
3695 TestNetLogEntry::List entries;
3696 log.GetEntries(&entries);
3697 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003698 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3699 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233700 ExpectLogContainsSomewhere(
3701 entries, pos,
mikecirone8b85c432016-09-08 19:11:003702 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3703 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233704
bnc691fda62016-08-12 00:43:163705 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233706 ASSERT_TRUE(response);
3707 ASSERT_TRUE(response->headers);
3708 EXPECT_TRUE(response->headers->IsKeepAlive());
3709 EXPECT_EQ(407, response->headers->response_code());
3710 EXPECT_EQ(10, response->headers->GetContentLength());
3711 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3712 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3713
3714 TestCompletionCallback callback2;
3715
3716 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163717 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3718 callback2.callback());
robpercival214763f2016-07-01 23:27:013719 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233720
bnc691fda62016-08-12 00:43:163721 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233722 ASSERT_TRUE(response);
3723 ASSERT_TRUE(response->headers);
3724 EXPECT_TRUE(response->headers->IsKeepAlive());
3725 EXPECT_EQ(407, response->headers->response_code());
3726 EXPECT_EQ(10, response->headers->GetContentLength());
3727 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3728 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3729
3730 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3731 // out of scope.
3732 session->CloseAllConnections();
3733 }
3734}
3735
3736// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3737// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3738// the case the server sends extra data on the original socket, so it can't be
3739// reused.
bncd16676a2016-07-20 16:23:013740TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273741 HttpRequestInfo request;
3742 request.method = "GET";
bncce36dca22015-04-21 22:11:233743 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273744 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293745 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103746 request.traffic_annotation =
3747 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273748
[email protected]2d2697f92009-02-18 21:00:323749 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593750 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493751 ProxyResolutionService::CreateFixedFromPacResult(
3752 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513753 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073754 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093755 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323756
[email protected]2d2697f92009-02-18 21:00:323757 // Since we have proxy, should try to establish tunnel.
3758 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233759 MockWrite(ASYNC, 0,
3760 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173761 "Host: www.example.org:443\r\n"
3762 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233763 };
[email protected]2d2697f92009-02-18 21:00:323764
mmenked39192ee2015-12-09 00:57:233765 // The proxy responds to the connect with a 407, using a persistent, but sends
3766 // extra data, so the socket cannot be reused.
3767 MockRead data_reads1[] = {
3768 // No credentials.
3769 MockRead(ASYNC, 1,
3770 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3771 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3772 "Content-Length: 10\r\n\r\n"),
3773 MockRead(SYNCHRONOUS, 2, "0123456789"),
3774 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3775 };
3776
3777 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233778 // After calling trans->RestartWithAuth(), this is the request we should
3779 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233780 MockWrite(ASYNC, 0,
3781 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173782 "Host: www.example.org:443\r\n"
3783 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233784 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3785
3786 MockWrite(ASYNC, 2,
3787 "GET / HTTP/1.1\r\n"
3788 "Host: www.example.org\r\n"
3789 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323790 };
3791
mmenked39192ee2015-12-09 00:57:233792 MockRead data_reads2[] = {
3793 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323794
mmenked39192ee2015-12-09 00:57:233795 MockRead(ASYNC, 3,
3796 "HTTP/1.1 200 OK\r\n"
3797 "Content-Type: text/html; charset=iso-8859-1\r\n"
3798 "Content-Length: 5\r\n\r\n"),
3799 // No response body because the test stops reading here.
3800 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323801 };
3802
Ryan Sleevib8d7ea02018-05-07 20:01:013803 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233804 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073805 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013806 SequencedSocketData data2(data_reads2, data_writes2);
mmenked39192ee2015-12-09 00:57:233807 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3808 SSLSocketDataProvider ssl(ASYNC, OK);
3809 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323810
[email protected]49639fa2011-12-20 23:22:413811 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323812
bnc87dcefc2017-05-25 12:47:583813 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193814 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323815
mmenked39192ee2015-12-09 00:57:233816 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013817 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233818
mmenke43758e62015-05-04 21:09:463819 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403820 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393821 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003822 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3823 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393824 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403825 entries, pos,
mikecirone8b85c432016-09-08 19:11:003826 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3827 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323828
[email protected]1c773ea12009-04-28 19:58:423829 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243830 ASSERT_TRUE(response);
3831 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323832 EXPECT_TRUE(response->headers->IsKeepAlive());
3833 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423834 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043835 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323836
mmenked39192ee2015-12-09 00:57:233837 LoadTimingInfo load_timing_info;
3838 // CONNECT requests and responses are handled at the connect job level, so
3839 // the transaction does not yet have a connection.
3840 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3841
[email protected]49639fa2011-12-20 23:22:413842 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323843
mmenked39192ee2015-12-09 00:57:233844 rv =
3845 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013846 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323847
[email protected]2d2697f92009-02-18 21:00:323848 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233849 EXPECT_EQ(200, response->headers->response_code());
3850 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423851 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133852
mmenked39192ee2015-12-09 00:57:233853 // The password prompt info should not be set.
3854 EXPECT_FALSE(response->auth_challenge);
3855
3856 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3857 TestLoadTimingNotReusedWithPac(load_timing_info,
3858 CONNECT_TIMING_HAS_SSL_TIMES);
3859
3860 trans.reset();
[email protected]102e27c2011-02-23 01:01:313861 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323862}
3863
mmenkee71e15332015-10-07 16:39:543864// Test the case a proxy closes a socket while the challenge body is being
3865// drained.
bncd16676a2016-07-20 16:23:013866TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543867 HttpRequestInfo request;
3868 request.method = "GET";
3869 request.url = GURL("https://www.example.org/");
3870 // Ensure that proxy authentication is attempted even
3871 // when the no authentication data flag is set.
3872 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103873 request.traffic_annotation =
3874 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543875
3876 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493877 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3878 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093879 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543880
bnc691fda62016-08-12 00:43:163881 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543882
3883 // Since we have proxy, should try to establish tunnel.
3884 MockWrite data_writes1[] = {
3885 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173886 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543887 "Proxy-Connection: keep-alive\r\n\r\n"),
3888 };
3889
3890 // The proxy responds to the connect with a 407, using a persistent
3891 // connection.
3892 MockRead data_reads1[] = {
3893 // No credentials.
3894 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3895 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3896 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3897 // Server hands up in the middle of the body.
3898 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3899 };
3900
3901 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163902 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543903 // be issuing -- the final header line contains the credentials.
3904 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173905 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543906 "Proxy-Connection: keep-alive\r\n"
3907 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3908
3909 MockWrite("GET / HTTP/1.1\r\n"
3910 "Host: www.example.org\r\n"
3911 "Connection: keep-alive\r\n\r\n"),
3912 };
3913
3914 MockRead data_reads2[] = {
3915 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3916
3917 MockRead("HTTP/1.1 200 OK\r\n"),
3918 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3919 MockRead("Content-Length: 5\r\n\r\n"),
3920 MockRead(SYNCHRONOUS, "hello"),
3921 };
3922
Ryan Sleevib8d7ea02018-05-07 20:01:013923 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenkee71e15332015-10-07 16:39:543924 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013925 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543926 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3927 SSLSocketDataProvider ssl(ASYNC, OK);
3928 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3929
3930 TestCompletionCallback callback;
3931
tfarina42834112016-09-22 13:38:203932 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013933 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543934
bnc691fda62016-08-12 00:43:163935 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543936 ASSERT_TRUE(response);
3937 ASSERT_TRUE(response->headers);
3938 EXPECT_TRUE(response->headers->IsKeepAlive());
3939 EXPECT_EQ(407, response->headers->response_code());
3940 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3941
bnc691fda62016-08-12 00:43:163942 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013943 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543944
bnc691fda62016-08-12 00:43:163945 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543946 ASSERT_TRUE(response);
3947 ASSERT_TRUE(response->headers);
3948 EXPECT_TRUE(response->headers->IsKeepAlive());
3949 EXPECT_EQ(200, response->headers->response_code());
3950 std::string body;
bnc691fda62016-08-12 00:43:163951 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543952 EXPECT_EQ("hello", body);
3953}
3954
[email protected]a8e9b162009-03-12 00:06:443955// Test that we don't read the response body when we fail to establish a tunnel,
3956// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013957TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273958 HttpRequestInfo request;
3959 request.method = "GET";
bncce36dca22015-04-21 22:11:233960 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103961 request.traffic_annotation =
3962 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273963
[email protected]a8e9b162009-03-12 00:06:443964 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493965 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3966 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443967
danakj1fd259a02016-04-16 03:17:093968 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443969
bnc691fda62016-08-12 00:43:163970 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443971
[email protected]a8e9b162009-03-12 00:06:443972 // Since we have proxy, should try to establish tunnel.
3973 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173974 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3975 "Host: www.example.org:443\r\n"
3976 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443977 };
3978
3979 // The proxy responds to the connect with a 407.
3980 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243981 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3982 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3983 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233984 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243985 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443986 };
3987
Ryan Sleevib8d7ea02018-05-07 20:01:013988 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:073989 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443990
[email protected]49639fa2011-12-20 23:22:413991 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443992
tfarina42834112016-09-22 13:38:203993 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443995
3996 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013997 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443998
bnc691fda62016-08-12 00:43:163999 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244000 ASSERT_TRUE(response);
4001 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:444002 EXPECT_TRUE(response->headers->IsKeepAlive());
4003 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:424004 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:444005
4006 std::string response_data;
bnc691fda62016-08-12 00:43:164007 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014008 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:184009
4010 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:314011 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:444012}
4013
ttuttle7933c112015-01-06 00:55:244014// Test that we don't pass extraneous headers from the proxy's response to the
4015// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:014016TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:244017 HttpRequestInfo request;
4018 request.method = "GET";
bncce36dca22015-04-21 22:11:234019 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104020 request.traffic_annotation =
4021 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244022
4023 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494024 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4025 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244026
danakj1fd259a02016-04-16 03:17:094027 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:244028
bnc691fda62016-08-12 00:43:164029 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:244030
4031 // Since we have proxy, should try to establish tunnel.
4032 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:174033 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4034 "Host: www.example.org:443\r\n"
4035 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:244036 };
4037
4038 // The proxy responds to the connect with a 407.
4039 MockRead data_reads[] = {
4040 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4041 MockRead("X-Foo: bar\r\n"),
4042 MockRead("Set-Cookie: foo=bar\r\n"),
4043 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4044 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:234045 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:244046 };
4047
Ryan Sleevib8d7ea02018-05-07 20:01:014048 StaticSocketDataProvider data(data_reads, data_writes);
ttuttle7933c112015-01-06 00:55:244049 session_deps_.socket_factory->AddSocketDataProvider(&data);
4050
4051 TestCompletionCallback callback;
4052
tfarina42834112016-09-22 13:38:204053 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014054 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:244055
4056 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014057 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:244058
bnc691fda62016-08-12 00:43:164059 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244060 ASSERT_TRUE(response);
4061 ASSERT_TRUE(response->headers);
4062 EXPECT_TRUE(response->headers->IsKeepAlive());
4063 EXPECT_EQ(407, response->headers->response_code());
4064 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4065 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
4066 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
4067
4068 std::string response_data;
bnc691fda62016-08-12 00:43:164069 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014070 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:244071
4072 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
4073 session->CloseAllConnections();
4074}
4075
[email protected]8fdbcd22010-05-05 02:54:524076// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
4077// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:014078TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:524079 HttpRequestInfo request;
4080 request.method = "GET";
bncce36dca22015-04-21 22:11:234081 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104082 request.traffic_annotation =
4083 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:524084
[email protected]cb9bf6ca2011-01-28 13:15:274085 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:094086 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:164087 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:274088
[email protected]8fdbcd22010-05-05 02:54:524089 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234090 MockWrite(
4091 "GET / HTTP/1.1\r\n"
4092 "Host: www.example.org\r\n"
4093 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:524094 };
4095
4096 MockRead data_reads1[] = {
4097 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
4098 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4099 // Large content-length -- won't matter, as connection will be reset.
4100 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064101 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:524102 };
4103
Ryan Sleevib8d7ea02018-05-07 20:01:014104 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074105 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:524106
[email protected]49639fa2011-12-20 23:22:414107 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:524108
tfarina42834112016-09-22 13:38:204109 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:524111
4112 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014113 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:524114}
4115
[email protected]7a67a8152010-11-05 18:31:104116// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
4117// through a non-authenticating proxy. The request should fail with
4118// ERR_UNEXPECTED_PROXY_AUTH.
4119// Note that it is impossible to detect if an HTTP server returns a 407 through
4120// a non-authenticating proxy - there is nothing to indicate whether the
4121// response came from the proxy or the server, so it is treated as if the proxy
4122// issued the challenge.
bncd16676a2016-07-20 16:23:014123TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:274124 HttpRequestInfo request;
4125 request.method = "GET";
bncce36dca22015-04-21 22:11:234126 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104127 request.traffic_annotation =
4128 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274129
Ramin Halavatica8d5252018-03-12 05:33:494130 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4131 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514132 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074133 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094134 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:104135
[email protected]7a67a8152010-11-05 18:31:104136 // Since we have proxy, should try to establish tunnel.
4137 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174138 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4139 "Host: www.example.org:443\r\n"
4140 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104141
rsleevidb16bb02015-11-12 23:47:174142 MockWrite("GET / HTTP/1.1\r\n"
4143 "Host: www.example.org\r\n"
4144 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104145 };
4146
4147 MockRead data_reads1[] = {
4148 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4149
4150 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
4151 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4152 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:064153 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:104154 };
4155
Ryan Sleevib8d7ea02018-05-07 20:01:014156 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074157 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064158 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074159 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:104160
[email protected]49639fa2011-12-20 23:22:414161 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:104162
bnc691fda62016-08-12 00:43:164163 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:104164
bnc691fda62016-08-12 00:43:164165 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014166 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:104167
4168 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014169 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464170 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404171 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104172 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004173 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4174 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104175 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404176 entries, pos,
mikecirone8b85c432016-09-08 19:11:004177 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4178 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104179}
[email protected]2df19bb2010-08-25 20:13:464180
mmenke2a1781d2015-10-07 19:25:334181// Test a proxy auth scheme that allows default credentials and a proxy server
4182// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014183TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334184 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4185 HttpRequestInfo request;
4186 request.method = "GET";
4187 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104188 request.traffic_annotation =
4189 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334190
4191 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594192 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494193 ProxyResolutionService::CreateFixedFromPacResult(
4194 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334195
Jeremy Roman0579ed62017-08-29 15:56:194196 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334197 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194198 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334199 mock_handler->set_allows_default_credentials(true);
4200 auth_handler_factory->AddMockHandler(mock_handler.release(),
4201 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484202 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334203
4204 // Add NetLog just so can verify load timing information gets a NetLog ID.
4205 NetLog net_log;
4206 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094207 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334208
4209 // Since we have proxy, should try to establish tunnel.
4210 MockWrite data_writes1[] = {
4211 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174212 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334213 "Proxy-Connection: keep-alive\r\n\r\n"),
4214 };
4215
4216 // The proxy responds to the connect with a 407, using a non-persistent
4217 // connection.
4218 MockRead data_reads1[] = {
4219 // No credentials.
4220 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4221 MockRead("Proxy-Authenticate: Mock\r\n"),
4222 MockRead("Proxy-Connection: close\r\n\r\n"),
4223 };
4224
4225 // Since the first connection couldn't be reused, need to establish another
4226 // once given credentials.
4227 MockWrite data_writes2[] = {
4228 // After calling trans->RestartWithAuth(), this is the request we should
4229 // be issuing -- the final header line contains the credentials.
4230 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174231 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334232 "Proxy-Connection: keep-alive\r\n"
4233 "Proxy-Authorization: auth_token\r\n\r\n"),
4234
4235 MockWrite("GET / HTTP/1.1\r\n"
4236 "Host: www.example.org\r\n"
4237 "Connection: keep-alive\r\n\r\n"),
4238 };
4239
4240 MockRead data_reads2[] = {
4241 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4242
4243 MockRead("HTTP/1.1 200 OK\r\n"),
4244 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4245 MockRead("Content-Length: 5\r\n\r\n"),
4246 MockRead(SYNCHRONOUS, "hello"),
4247 };
4248
Ryan Sleevib8d7ea02018-05-07 20:01:014249 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334250 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014251 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334252 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4253 SSLSocketDataProvider ssl(ASYNC, OK);
4254 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4255
bnc87dcefc2017-05-25 12:47:584256 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194257 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334258
4259 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204260 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014261 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334262
4263 const HttpResponseInfo* response = trans->GetResponseInfo();
4264 ASSERT_TRUE(response);
4265 ASSERT_TRUE(response->headers);
4266 EXPECT_FALSE(response->headers->IsKeepAlive());
4267 EXPECT_EQ(407, response->headers->response_code());
4268 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4269 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524270 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334271
4272 LoadTimingInfo load_timing_info;
4273 // CONNECT requests and responses are handled at the connect job level, so
4274 // the transaction does not yet have a connection.
4275 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4276
4277 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014278 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334279 response = trans->GetResponseInfo();
4280 ASSERT_TRUE(response);
4281 ASSERT_TRUE(response->headers);
4282 EXPECT_TRUE(response->headers->IsKeepAlive());
4283 EXPECT_EQ(200, response->headers->response_code());
4284 EXPECT_EQ(5, response->headers->GetContentLength());
4285 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4286
4287 // The password prompt info should not be set.
4288 EXPECT_FALSE(response->auth_challenge);
4289
4290 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4291 TestLoadTimingNotReusedWithPac(load_timing_info,
4292 CONNECT_TIMING_HAS_SSL_TIMES);
4293
4294 trans.reset();
4295 session->CloseAllConnections();
4296}
4297
4298// Test a proxy auth scheme that allows default credentials and a proxy server
4299// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014300TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334301 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4302 HttpRequestInfo request;
4303 request.method = "GET";
4304 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104305 request.traffic_annotation =
4306 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334307
4308 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594309 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494310 ProxyResolutionService::CreateFixedFromPacResult(
4311 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334312
Jeremy Roman0579ed62017-08-29 15:56:194313 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334314 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194315 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334316 mock_handler->set_allows_default_credentials(true);
4317 auth_handler_factory->AddMockHandler(mock_handler.release(),
4318 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484319 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334320
4321 // Add NetLog just so can verify load timing information gets a NetLog ID.
4322 NetLog net_log;
4323 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094324 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334325
4326 // Should try to establish tunnel.
4327 MockWrite data_writes1[] = {
4328 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174329 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334330 "Proxy-Connection: keep-alive\r\n\r\n"),
4331
4332 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174333 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334334 "Proxy-Connection: keep-alive\r\n"
4335 "Proxy-Authorization: auth_token\r\n\r\n"),
4336 };
4337
4338 // The proxy responds to the connect with a 407, using a non-persistent
4339 // connection.
4340 MockRead data_reads1[] = {
4341 // No credentials.
4342 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4343 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4344 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4345 };
4346
4347 // Since the first connection was closed, need to establish another once given
4348 // credentials.
4349 MockWrite data_writes2[] = {
4350 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174351 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334352 "Proxy-Connection: keep-alive\r\n"
4353 "Proxy-Authorization: auth_token\r\n\r\n"),
4354
4355 MockWrite("GET / HTTP/1.1\r\n"
4356 "Host: www.example.org\r\n"
4357 "Connection: keep-alive\r\n\r\n"),
4358 };
4359
4360 MockRead data_reads2[] = {
4361 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4362
4363 MockRead("HTTP/1.1 200 OK\r\n"),
4364 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4365 MockRead("Content-Length: 5\r\n\r\n"),
4366 MockRead(SYNCHRONOUS, "hello"),
4367 };
4368
Ryan Sleevib8d7ea02018-05-07 20:01:014369 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334370 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014371 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334372 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4373 SSLSocketDataProvider ssl(ASYNC, OK);
4374 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4375
bnc87dcefc2017-05-25 12:47:584376 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194377 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334378
4379 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204380 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014381 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334382
4383 const HttpResponseInfo* response = trans->GetResponseInfo();
4384 ASSERT_TRUE(response);
4385 ASSERT_TRUE(response->headers);
4386 EXPECT_TRUE(response->headers->IsKeepAlive());
4387 EXPECT_EQ(407, response->headers->response_code());
4388 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4389 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4390 EXPECT_FALSE(response->auth_challenge);
4391
4392 LoadTimingInfo load_timing_info;
4393 // CONNECT requests and responses are handled at the connect job level, so
4394 // the transaction does not yet have a connection.
4395 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4396
4397 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014398 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334399
4400 response = trans->GetResponseInfo();
4401 ASSERT_TRUE(response);
4402 ASSERT_TRUE(response->headers);
4403 EXPECT_TRUE(response->headers->IsKeepAlive());
4404 EXPECT_EQ(200, response->headers->response_code());
4405 EXPECT_EQ(5, response->headers->GetContentLength());
4406 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4407
4408 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524409 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334410
4411 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4412 TestLoadTimingNotReusedWithPac(load_timing_info,
4413 CONNECT_TIMING_HAS_SSL_TIMES);
4414
4415 trans.reset();
4416 session->CloseAllConnections();
4417}
4418
4419// Test a proxy auth scheme that allows default credentials and a proxy server
4420// that hangs up when credentials are initially sent, and hangs up again when
4421// they are retried.
bncd16676a2016-07-20 16:23:014422TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334423 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4424 HttpRequestInfo request;
4425 request.method = "GET";
4426 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104427 request.traffic_annotation =
4428 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334429
4430 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594431 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494432 ProxyResolutionService::CreateFixedFromPacResult(
4433 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334434
Jeremy Roman0579ed62017-08-29 15:56:194435 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334436 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194437 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334438 mock_handler->set_allows_default_credentials(true);
4439 auth_handler_factory->AddMockHandler(mock_handler.release(),
4440 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484441 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334442
4443 // Add NetLog just so can verify load timing information gets a NetLog ID.
4444 NetLog net_log;
4445 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094446 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334447
4448 // Should try to establish tunnel.
4449 MockWrite data_writes1[] = {
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\r\n"),
4453
4454 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174455 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334456 "Proxy-Connection: keep-alive\r\n"
4457 "Proxy-Authorization: auth_token\r\n\r\n"),
4458 };
4459
4460 // The proxy responds to the connect with a 407, and then hangs up after the
4461 // second request is sent.
4462 MockRead data_reads1[] = {
4463 // No credentials.
4464 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4465 MockRead("Content-Length: 0\r\n"),
4466 MockRead("Proxy-Connection: keep-alive\r\n"),
4467 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4468 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4469 };
4470
4471 // HttpNetworkTransaction sees a reused connection that was closed with
4472 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4473 // request.
4474 MockWrite data_writes2[] = {
4475 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174476 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334477 "Proxy-Connection: keep-alive\r\n\r\n"),
4478 };
4479
4480 // The proxy, having had more than enough of us, just hangs up.
4481 MockRead data_reads2[] = {
4482 // No credentials.
4483 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4484 };
4485
Ryan Sleevib8d7ea02018-05-07 20:01:014486 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334487 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014488 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334489 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4490
bnc87dcefc2017-05-25 12:47:584491 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194492 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334493
4494 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204495 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014496 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334497
4498 const HttpResponseInfo* response = trans->GetResponseInfo();
4499 ASSERT_TRUE(response);
4500 ASSERT_TRUE(response->headers);
4501 EXPECT_TRUE(response->headers->IsKeepAlive());
4502 EXPECT_EQ(407, response->headers->response_code());
4503 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4504 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4505 EXPECT_FALSE(response->auth_challenge);
4506
4507 LoadTimingInfo load_timing_info;
4508 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4509
4510 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014511 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334512
4513 trans.reset();
4514 session->CloseAllConnections();
4515}
4516
Asanka Herathbc3f8f62018-11-16 23:08:304517// This test exercises an odd edge case where the proxy closes the connection
4518// after the authentication handshake is complete. Presumably this technique is
4519// used in lieu of returning a 403 or 5xx status code when the authentication
4520// succeeds, but the user is not authorized to connect to the destination
4521// server. There's no standard for what a proxy should do to indicate a blocked
4522// site.
4523TEST_F(HttpNetworkTransactionTest,
4524 AuthAllowsDefaultCredentialsTunnelConnectionClosesBeforeBody) {
4525 HttpRequestInfo request;
4526 request.method = "GET";
4527 request.url = GURL("https://www.example.org/");
4528 request.traffic_annotation =
4529 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4530
4531 // Configure against proxy server "myproxy:70".
4532 session_deps_.proxy_resolution_service =
4533 ProxyResolutionService::CreateFixedFromPacResult(
4534 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4535
Steven Valdez0ef94d02018-11-19 23:28:134536 // When TLS 1.3 is enabled, spurious connections are made as part of the SSL
4537 // version interference probes.
4538 // TODO(crbug.com/906668): Correctly handle version interference probes to
4539 // test TLS 1.3.
4540 SSLConfig config;
4541 config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
4542 session_deps_.ssl_config_service =
4543 std::make_unique<TestSSLConfigService>(config);
4544
Asanka Herathbc3f8f62018-11-16 23:08:304545 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
4546 auth_handler_factory->set_do_init_from_challenge(true);
4547
4548 // Create two mock AuthHandlers. This is because the transaction gets retried
4549 // after the first ERR_CONNECTION_CLOSED since it's ambiguous whether there
4550 // was a real network error.
4551 //
4552 // The handlers support both default and explicit credentials. The retry
4553 // mentioned above should be able to reuse the default identity. Thus there
4554 // should never be a need to prompt for explicit credentials.
4555 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
4556 mock_handler->set_allows_default_credentials(true);
4557 mock_handler->set_allows_explicit_credentials(true);
4558 mock_handler->set_connection_based(true);
4559 auth_handler_factory->AddMockHandler(mock_handler.release(),
4560 HttpAuth::AUTH_PROXY);
4561 mock_handler = std::make_unique<HttpAuthHandlerMock>();
4562 mock_handler->set_allows_default_credentials(true);
4563 mock_handler->set_allows_explicit_credentials(true);
4564 mock_handler->set_connection_based(true);
4565 auth_handler_factory->AddMockHandler(mock_handler.release(),
4566 HttpAuth::AUTH_PROXY);
4567 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4568
4569 NetLog net_log;
4570 session_deps_.net_log = &net_log;
4571 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4572
4573 // Data for both sockets.
4574 //
4575 // Writes are for the tunnel establishment attempts and the
4576 // authentication handshake.
4577 MockWrite data_writes1[] = {
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\r\n"),
4581
4582 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4583 "Host: www.example.org:443\r\n"
4584 "Proxy-Connection: keep-alive\r\n"
4585 "Proxy-Authorization: auth_token\r\n\r\n"),
4586
4587 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4588 "Host: www.example.org:443\r\n"
4589 "Proxy-Connection: keep-alive\r\n"
4590 "Proxy-Authorization: auth_token\r\n\r\n"),
4591 };
4592
4593 // The server side of the authentication handshake. Note that the response to
4594 // the final CONNECT request is ERR_CONNECTION_CLOSED.
4595 MockRead data_reads1[] = {
4596 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4597 MockRead("Content-Length: 0\r\n"),
4598 MockRead("Proxy-Connection: keep-alive\r\n"),
4599 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4600
4601 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4602 MockRead("Content-Length: 0\r\n"),
4603 MockRead("Proxy-Connection: keep-alive\r\n"),
4604 MockRead("Proxy-Authenticate: Mock foo\r\n\r\n"),
4605
4606 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4607 };
4608
4609 StaticSocketDataProvider data1(data_reads1, data_writes1);
4610 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4611
4612 // The second socket is for the reconnection attempt. Data is identical to the
4613 // first attempt.
4614 StaticSocketDataProvider data2(data_reads1, data_writes1);
4615 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4616
4617 auto trans =
4618 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4619
4620 TestCompletionCallback callback;
4621 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4622
4623 // Two rounds per handshake. After one retry, the error is propagated up the
4624 // stack.
4625 for (int i = 0; i < 4; ++i) {
4626 EXPECT_THAT(callback.GetResult(rv), IsOk());
4627
4628 const HttpResponseInfo* response = trans->GetResponseInfo();
4629 ASSERT_TRUE(response);
4630 ASSERT_TRUE(response->headers);
4631 EXPECT_EQ(407, response->headers->response_code());
4632 ASSERT_TRUE(trans->IsReadyToRestartForAuth());
4633
4634 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4635 }
4636
4637 // One shall be the number thou shalt retry, and the number of the retrying
4638 // shall be one. Two shalt thou not retry, neither retry thou zero, excepting
4639 // that thou then proceed to one. Three is right out. Once the number one,
4640 // being the first number, be reached, then lobbest thou thy
4641 // ERR_CONNECTION_CLOSED towards they network transaction, who shall snuff it.
4642 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.GetResult(rv));
4643
4644 trans.reset();
4645 session->CloseAllConnections();
4646}
4647
mmenke2a1781d2015-10-07 19:25:334648// Test a proxy auth scheme that allows default credentials and a proxy server
4649// that hangs up when credentials are initially sent, and sends a challenge
4650// again they are retried.
bncd16676a2016-07-20 16:23:014651TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334652 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4653 HttpRequestInfo request;
4654 request.method = "GET";
4655 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104656 request.traffic_annotation =
4657 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334658
4659 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594660 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494661 ProxyResolutionService::CreateFixedFromPacResult(
4662 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334663
Jeremy Roman0579ed62017-08-29 15:56:194664 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334665 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194666 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334667 mock_handler->set_allows_default_credentials(true);
4668 auth_handler_factory->AddMockHandler(mock_handler.release(),
4669 HttpAuth::AUTH_PROXY);
4670 // Add another handler for the second challenge. It supports default
4671 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194672 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334673 mock_handler->set_allows_default_credentials(true);
4674 auth_handler_factory->AddMockHandler(mock_handler.release(),
4675 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484676 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334677
4678 // Add NetLog just so can verify load timing information gets a NetLog ID.
4679 NetLog net_log;
4680 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094681 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334682
4683 // Should try to establish tunnel.
4684 MockWrite data_writes1[] = {
4685 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174686 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334687 "Proxy-Connection: keep-alive\r\n\r\n"),
4688 };
4689
4690 // The proxy responds to the connect with a 407, using a non-persistent
4691 // connection.
4692 MockRead data_reads1[] = {
4693 // No credentials.
4694 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4695 MockRead("Proxy-Authenticate: Mock\r\n"),
4696 MockRead("Proxy-Connection: close\r\n\r\n"),
4697 };
4698
4699 // Since the first connection was closed, need to establish another once given
4700 // credentials.
4701 MockWrite data_writes2[] = {
4702 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174703 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334704 "Proxy-Connection: keep-alive\r\n"
4705 "Proxy-Authorization: auth_token\r\n\r\n"),
4706 };
4707
4708 MockRead data_reads2[] = {
4709 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4710 MockRead("Proxy-Authenticate: Mock\r\n"),
4711 MockRead("Proxy-Connection: close\r\n\r\n"),
4712 };
4713
Ryan Sleevib8d7ea02018-05-07 20:01:014714 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334715 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014716 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334717 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4718 SSLSocketDataProvider ssl(ASYNC, OK);
4719 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4720
bnc87dcefc2017-05-25 12:47:584721 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194722 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334723
4724 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204725 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014726 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334727
4728 const HttpResponseInfo* response = trans->GetResponseInfo();
4729 ASSERT_TRUE(response);
4730 ASSERT_TRUE(response->headers);
4731 EXPECT_EQ(407, response->headers->response_code());
4732 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4733 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4734 EXPECT_FALSE(response->auth_challenge);
4735
4736 LoadTimingInfo load_timing_info;
4737 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4738
4739 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014740 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334741 response = trans->GetResponseInfo();
4742 ASSERT_TRUE(response);
4743 ASSERT_TRUE(response->headers);
4744 EXPECT_EQ(407, response->headers->response_code());
4745 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4746 EXPECT_TRUE(response->auth_challenge);
4747
4748 trans.reset();
4749 session->CloseAllConnections();
4750}
4751
asankae2257db2016-10-11 22:03:164752// A more nuanced test than GenerateAuthToken test which asserts that
4753// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4754// unnecessarily invalidated, and that if the server co-operates, the
4755// authentication handshake can continue with the same scheme but with a
4756// different identity.
4757TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4758 HttpRequestInfo request;
4759 request.method = "GET";
4760 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104761 request.traffic_annotation =
4762 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164763
Jeremy Roman0579ed62017-08-29 15:56:194764 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164765 auth_handler_factory->set_do_init_from_challenge(true);
4766
4767 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194768 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164769 mock_handler->set_allows_default_credentials(true);
4770 mock_handler->set_allows_explicit_credentials(true);
4771 mock_handler->set_connection_based(true);
4772 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4773 auth_handler_factory->AddMockHandler(mock_handler.release(),
4774 HttpAuth::AUTH_SERVER);
4775
4776 // Add another handler for the second challenge. It supports default
4777 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194778 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164779 mock_handler->set_allows_default_credentials(true);
4780 mock_handler->set_allows_explicit_credentials(true);
4781 mock_handler->set_connection_based(true);
4782 auth_handler_factory->AddMockHandler(mock_handler.release(),
4783 HttpAuth::AUTH_SERVER);
4784 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4785
4786 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4787
4788 MockWrite data_writes1[] = {
4789 MockWrite("GET / HTTP/1.1\r\n"
4790 "Host: www.example.org\r\n"
4791 "Connection: keep-alive\r\n\r\n"),
4792 };
4793
4794 MockRead data_reads1[] = {
4795 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4796 "WWW-Authenticate: Mock\r\n"
4797 "Connection: keep-alive\r\n\r\n"),
4798 };
4799
4800 // Identical to data_writes1[]. The AuthHandler encounters a
4801 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4802 // transaction procceds without an authorization header.
4803 MockWrite data_writes2[] = {
4804 MockWrite("GET / HTTP/1.1\r\n"
4805 "Host: www.example.org\r\n"
4806 "Connection: keep-alive\r\n\r\n"),
4807 };
4808
4809 MockRead data_reads2[] = {
4810 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4811 "WWW-Authenticate: Mock\r\n"
4812 "Connection: keep-alive\r\n\r\n"),
4813 };
4814
4815 MockWrite data_writes3[] = {
4816 MockWrite("GET / HTTP/1.1\r\n"
4817 "Host: www.example.org\r\n"
4818 "Connection: keep-alive\r\n"
4819 "Authorization: auth_token\r\n\r\n"),
4820 };
4821
4822 MockRead data_reads3[] = {
4823 MockRead("HTTP/1.1 200 OK\r\n"
4824 "Content-Length: 5\r\n"
4825 "Content-Type: text/plain\r\n"
4826 "Connection: keep-alive\r\n\r\n"
4827 "Hello"),
4828 };
4829
Ryan Sleevib8d7ea02018-05-07 20:01:014830 StaticSocketDataProvider data1(data_reads1, data_writes1);
asankae2257db2016-10-11 22:03:164831 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4832
Ryan Sleevib8d7ea02018-05-07 20:01:014833 StaticSocketDataProvider data2(data_reads2, data_writes2);
asankae2257db2016-10-11 22:03:164834 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4835
Ryan Sleevib8d7ea02018-05-07 20:01:014836 StaticSocketDataProvider data3(data_reads3, data_writes3);
asankae2257db2016-10-11 22:03:164837 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4838
bnc87dcefc2017-05-25 12:47:584839 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194840 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164841
4842 TestCompletionCallback callback;
4843 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4844 EXPECT_THAT(callback.GetResult(rv), IsOk());
4845
4846 const HttpResponseInfo* response = trans->GetResponseInfo();
4847 ASSERT_TRUE(response);
4848 ASSERT_TRUE(response->headers);
4849 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4850
4851 // The following three tests assert that an authentication challenge was
4852 // received and that the stack is ready to respond to the challenge using
4853 // ambient credentials.
4854 EXPECT_EQ(401, response->headers->response_code());
4855 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4856 EXPECT_FALSE(response->auth_challenge);
4857
4858 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4859 EXPECT_THAT(callback.GetResult(rv), IsOk());
4860 response = trans->GetResponseInfo();
4861 ASSERT_TRUE(response);
4862 ASSERT_TRUE(response->headers);
4863
4864 // The following three tests assert that an authentication challenge was
4865 // received and that the stack needs explicit credentials before it is ready
4866 // to respond to the challenge.
4867 EXPECT_EQ(401, response->headers->response_code());
4868 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4869 EXPECT_TRUE(response->auth_challenge);
4870
4871 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4872 EXPECT_THAT(callback.GetResult(rv), IsOk());
4873 response = trans->GetResponseInfo();
4874 ASSERT_TRUE(response);
4875 ASSERT_TRUE(response->headers);
4876 EXPECT_EQ(200, response->headers->response_code());
4877
4878 trans.reset();
4879 session->CloseAllConnections();
4880}
4881
Matt Menked1eb6d42018-01-17 04:54:064882// Proxy resolver that returns a proxy with the same host and port for different
4883// schemes, based on the path of the URL being requests.
4884class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4885 public:
4886 SameProxyWithDifferentSchemesProxyResolver() {}
4887 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4888
4889 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4890
4891 static HostPortPair ProxyHostPortPair() {
4892 return HostPortPair::FromString(ProxyHostPortPairAsString());
4893 }
4894
4895 // ProxyResolver implementation.
4896 int GetProxyForURL(const GURL& url,
4897 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:174898 CompletionOnceCallback callback,
Matt Menked1eb6d42018-01-17 04:54:064899 std::unique_ptr<Request>* request,
4900 const NetLogWithSource& /*net_log*/) override {
4901 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574902 results->set_traffic_annotation(
4903 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064904 if (url.path() == "/socks4") {
4905 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4906 return OK;
4907 }
4908 if (url.path() == "/socks5") {
4909 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4910 return OK;
4911 }
4912 if (url.path() == "/http") {
4913 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4914 return OK;
4915 }
4916 if (url.path() == "/https") {
4917 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4918 return OK;
4919 }
Matt Menkee8648fa2019-01-17 16:47:074920 if (url.path() == "/https_trusted") {
4921 results->UseProxyServer(ProxyServer(ProxyServer::SCHEME_HTTPS,
4922 ProxyHostPortPair(),
4923 true /* is_trusted_proxy */));
4924 return OK;
4925 }
Matt Menked1eb6d42018-01-17 04:54:064926 NOTREACHED();
4927 return ERR_NOT_IMPLEMENTED;
4928 }
4929
4930 private:
4931 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4932};
4933
4934class SameProxyWithDifferentSchemesProxyResolverFactory
4935 : public ProxyResolverFactory {
4936 public:
4937 SameProxyWithDifferentSchemesProxyResolverFactory()
4938 : ProxyResolverFactory(false) {}
4939
Lily Houghton99597862018-03-07 16:40:424940 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4941 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:174942 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:424943 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064944 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4945 return OK;
4946 }
4947
4948 private:
4949 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4950};
4951
4952// Check that when different proxy schemes are all applied to a proxy at the
Matt Menkee8648fa2019-01-17 16:47:074953// same address, the connections are not grouped together. i.e., a request to
Matt Menked1eb6d42018-01-17 04:54:064954// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4955// request to foo.com using proxy.com as an HTTP proxy.
4956TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494957 session_deps_.proxy_resolution_service =
4958 std::make_unique<ProxyResolutionService>(
4959 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4960 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4961 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4962 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064963
4964 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4965
4966 MockWrite socks_writes[] = {
4967 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4968 kSOCKS4OkRequestLocalHostPort80Length),
4969 MockWrite(SYNCHRONOUS,
4970 "GET /socks4 HTTP/1.1\r\n"
4971 "Host: test\r\n"
4972 "Connection: keep-alive\r\n\r\n"),
4973 };
4974 MockRead socks_reads[] = {
4975 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4976 MockRead("HTTP/1.0 200 OK\r\n"
4977 "Connection: keep-alive\r\n"
4978 "Content-Length: 15\r\n\r\n"
4979 "SOCKS4 Response"),
4980 };
Ryan Sleevib8d7ea02018-05-07 20:01:014981 StaticSocketDataProvider socks_data(socks_reads, socks_writes);
Matt Menked1eb6d42018-01-17 04:54:064982 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4983
4984 const char kSOCKS5Request[] = {
4985 0x05, // Version
4986 0x01, // Command (CONNECT)
4987 0x00, // Reserved
4988 0x03, // Address type (DOMAINNAME)
4989 0x04, // Length of domain (4)
4990 't', 'e', 's', 't', // Domain string
4991 0x00, 0x50, // 16-bit port (80)
4992 };
4993 MockWrite socks5_writes[] = {
4994 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Avi Drissman4365a4782018-12-28 19:26:244995 MockWrite(ASYNC, kSOCKS5Request, base::size(kSOCKS5Request)),
Matt Menked1eb6d42018-01-17 04:54:064996 MockWrite(SYNCHRONOUS,
4997 "GET /socks5 HTTP/1.1\r\n"
4998 "Host: test\r\n"
4999 "Connection: keep-alive\r\n\r\n"),
5000 };
5001 MockRead socks5_reads[] = {
5002 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
5003 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
5004 MockRead("HTTP/1.0 200 OK\r\n"
5005 "Connection: keep-alive\r\n"
5006 "Content-Length: 15\r\n\r\n"
5007 "SOCKS5 Response"),
5008 };
Ryan Sleevib8d7ea02018-05-07 20:01:015009 StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
Matt Menked1eb6d42018-01-17 04:54:065010 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
5011
5012 MockWrite http_writes[] = {
5013 MockWrite(SYNCHRONOUS,
5014 "GET http://test/http HTTP/1.1\r\n"
5015 "Host: test\r\n"
5016 "Proxy-Connection: keep-alive\r\n\r\n"),
5017 };
5018 MockRead http_reads[] = {
5019 MockRead("HTTP/1.1 200 OK\r\n"
5020 "Proxy-Connection: keep-alive\r\n"
5021 "Content-Length: 13\r\n\r\n"
5022 "HTTP Response"),
5023 };
Ryan Sleevib8d7ea02018-05-07 20:01:015024 StaticSocketDataProvider http_data(http_reads, http_writes);
Matt Menked1eb6d42018-01-17 04:54:065025 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
5026
5027 MockWrite https_writes[] = {
5028 MockWrite(SYNCHRONOUS,
5029 "GET http://test/https HTTP/1.1\r\n"
5030 "Host: test\r\n"
5031 "Proxy-Connection: keep-alive\r\n\r\n"),
5032 };
5033 MockRead https_reads[] = {
5034 MockRead("HTTP/1.1 200 OK\r\n"
5035 "Proxy-Connection: keep-alive\r\n"
5036 "Content-Length: 14\r\n\r\n"
5037 "HTTPS Response"),
5038 };
Ryan Sleevib8d7ea02018-05-07 20:01:015039 StaticSocketDataProvider https_data(https_reads, https_writes);
Matt Menked1eb6d42018-01-17 04:54:065040 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
5041 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
5042 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5043
Matt Menkee8648fa2019-01-17 16:47:075044 MockWrite https_trusted_writes[] = {
5045 MockWrite(SYNCHRONOUS,
5046 "GET http://test/https_trusted HTTP/1.1\r\n"
5047 "Host: test\r\n"
5048 "Proxy-Connection: keep-alive\r\n\r\n"),
5049 };
5050 MockRead https_trusted_reads[] = {
5051 MockRead("HTTP/1.1 200 OK\r\n"
5052 "Proxy-Connection: keep-alive\r\n"
5053 "Content-Length: 22\r\n\r\n"
5054 "HTTPS Trusted Response"),
5055 };
5056 StaticSocketDataProvider trusted_https_data(https_trusted_reads,
5057 https_trusted_writes);
5058 session_deps_.socket_factory->AddSocketDataProvider(&trusted_https_data);
5059 SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
5060 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
5061
Matt Menked1eb6d42018-01-17 04:54:065062 struct TestCase {
5063 GURL url;
5064 std::string expected_response;
Matt Menkee8648fa2019-01-17 16:47:075065 // How many idle sockets there should be in the SOCKS 4/5 proxy socket pools
Matt Menked1eb6d42018-01-17 04:54:065066 // after the test.
Matt Menkee8648fa2019-01-17 16:47:075067 int expected_idle_socks4_sockets;
5068 int expected_idle_socks5_sockets;
5069 // How many idle sockets there should be in the HTTP/HTTPS proxy socket
5070 // pools after the test.
Matt Menked1eb6d42018-01-17 04:54:065071 int expected_idle_http_sockets;
Matt Menkee8648fa2019-01-17 16:47:075072 int expected_idle_https_sockets;
5073 // How many idle sockets there should be in the HTTPS proxy socket pool with
5074 // the ProxyServer's |is_trusted_proxy| bit set after the test.
5075 int expected_idle_trusted_https_sockets;
Matt Menked1eb6d42018-01-17 04:54:065076 } const kTestCases[] = {
Matt Menkee8648fa2019-01-17 16:47:075077 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0, 0, 0, 0},
5078 {GURL("http://test/socks5"), "SOCKS5 Response", 1, 1, 0, 0, 0},
5079 {GURL("http://test/http"), "HTTP Response", 1, 1, 1, 0, 0},
5080 {GURL("http://test/https"), "HTTPS Response", 1, 1, 1, 1, 0},
5081 {GURL("http://test/https_trusted"), "HTTPS Trusted Response", 1, 1, 1, 1,
5082 1},
Matt Menked1eb6d42018-01-17 04:54:065083 };
5084
5085 for (const auto& test_case : kTestCases) {
5086 HttpRequestInfo request;
5087 request.method = "GET";
5088 request.url = test_case.url;
Ramin Halavatib5e433e62018-02-07 07:41:105089 request.traffic_annotation =
5090 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:065091 std::unique_ptr<HttpNetworkTransaction> trans =
5092 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
5093 session.get());
5094 TestCompletionCallback callback;
5095 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5096 EXPECT_THAT(callback.GetResult(rv), IsOk());
5097
5098 const HttpResponseInfo* response = trans->GetResponseInfo();
5099 ASSERT_TRUE(response);
5100 ASSERT_TRUE(response->headers);
5101 EXPECT_EQ(200, response->headers->response_code());
5102 std::string response_data;
5103 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
5104 EXPECT_EQ(test_case.expected_response, response_data);
5105
5106 // Return the socket to the socket pool, so can make sure it's not used for
5107 // the next requests.
5108 trans.reset();
5109 base::RunLoop().RunUntilIdle();
5110
5111 // Check the number of idle sockets in the pool, to make sure that used
5112 // sockets are indeed being returned to the socket pool. If each request
5113 // doesn't return an idle socket to the pool, the test would incorrectly
5114 // pass.
Matt Menkee8648fa2019-01-17 16:47:075115 EXPECT_EQ(test_case.expected_idle_socks4_sockets,
5116 session
Matt Menked23ab952019-03-06 00:24:405117 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075118 HttpNetworkSession::NORMAL_SOCKET_POOL,
5119 ProxyServer(ProxyServer::SCHEME_SOCKS4,
5120 SameProxyWithDifferentSchemesProxyResolver::
5121 ProxyHostPortPair()))
5122 ->IdleSocketCount());
5123 EXPECT_EQ(test_case.expected_idle_socks5_sockets,
5124 session
Matt Menked23ab952019-03-06 00:24:405125 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075126 HttpNetworkSession::NORMAL_SOCKET_POOL,
5127 ProxyServer(ProxyServer::SCHEME_SOCKS5,
5128 SameProxyWithDifferentSchemesProxyResolver::
5129 ProxyHostPortPair()))
5130 ->IdleSocketCount());
5131 EXPECT_EQ(test_case.expected_idle_http_sockets,
5132 session
Matt Menked23ab952019-03-06 00:24:405133 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075134 HttpNetworkSession::NORMAL_SOCKET_POOL,
5135 ProxyServer(ProxyServer::SCHEME_HTTP,
5136 SameProxyWithDifferentSchemesProxyResolver::
5137 ProxyHostPortPair()))
5138 ->IdleSocketCount());
5139 EXPECT_EQ(test_case.expected_idle_https_sockets,
5140 session
Matt Menked23ab952019-03-06 00:24:405141 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075142 HttpNetworkSession::NORMAL_SOCKET_POOL,
5143 ProxyServer(ProxyServer::SCHEME_HTTPS,
5144 SameProxyWithDifferentSchemesProxyResolver::
5145 ProxyHostPortPair()))
5146 ->IdleSocketCount());
5147 EXPECT_EQ(test_case.expected_idle_trusted_https_sockets,
5148 session
Matt Menked23ab952019-03-06 00:24:405149 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075150 HttpNetworkSession::NORMAL_SOCKET_POOL,
5151 ProxyServer(ProxyServer::SCHEME_HTTPS,
5152 SameProxyWithDifferentSchemesProxyResolver::
5153 ProxyHostPortPair(),
5154 true /* is_trusted_proxy */))
5155 ->IdleSocketCount());
Matt Menked1eb6d42018-01-17 04:54:065156 }
5157}
5158
[email protected]029c83b62013-01-24 05:28:205159// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:015160TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205161 HttpRequestInfo request1;
5162 request1.method = "GET";
bncce36dca22015-04-21 22:11:235163 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:105164 request1.traffic_annotation =
5165 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205166
5167 HttpRequestInfo request2;
5168 request2.method = "GET";
bncce36dca22015-04-21 22:11:235169 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:105170 request2.traffic_annotation =
5171 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205172
5173 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495174 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5175 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515176 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075177 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095178 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205179
5180 // Since we have proxy, should try to establish tunnel.
5181 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175182 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5183 "Host: www.example.org:443\r\n"
5184 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205185
rsleevidb16bb02015-11-12 23:47:175186 MockWrite("GET /1 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
rsleevidb16bb02015-11-12 23:47:175190 MockWrite("GET /2 HTTP/1.1\r\n"
5191 "Host: www.example.org\r\n"
5192 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205193 };
5194
5195 // The proxy responds to the connect with a 407, using a persistent
5196 // connection.
5197 MockRead data_reads1[] = {
5198 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5199
5200 MockRead("HTTP/1.1 200 OK\r\n"),
5201 MockRead("Content-Length: 1\r\n\r\n"),
5202 MockRead(SYNCHRONOUS, "1"),
5203
5204 MockRead("HTTP/1.1 200 OK\r\n"),
5205 MockRead("Content-Length: 2\r\n\r\n"),
5206 MockRead(SYNCHRONOUS, "22"),
5207 };
5208
Ryan Sleevib8d7ea02018-05-07 20:01:015209 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075210 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205211 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075212 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205213
5214 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585215 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195216 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205217
5218 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015219 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205220
5221 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015222 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205223
5224 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525225 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:475226 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:525227 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205228 EXPECT_EQ(1, response1->headers->GetContentLength());
5229
5230 LoadTimingInfo load_timing_info1;
5231 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5232 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
5233
5234 trans1.reset();
5235
5236 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585237 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195238 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205239
5240 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015241 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205242
5243 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015244 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205245
5246 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525247 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:475248 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:525249 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205250 EXPECT_EQ(2, response2->headers->GetContentLength());
5251
5252 LoadTimingInfo load_timing_info2;
5253 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5254 TestLoadTimingReused(load_timing_info2);
5255
5256 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5257
5258 trans2.reset();
5259 session->CloseAllConnections();
5260}
5261
5262// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:015263TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205264 HttpRequestInfo request1;
5265 request1.method = "GET";
bncce36dca22015-04-21 22:11:235266 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:105267 request1.traffic_annotation =
5268 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205269
5270 HttpRequestInfo request2;
5271 request2.method = "GET";
bncce36dca22015-04-21 22:11:235272 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:105273 request2.traffic_annotation =
5274 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205275
5276 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595277 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:495278 ProxyResolutionService::CreateFixedFromPacResult(
5279 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515280 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075281 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095282 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205283
5284 // Since we have proxy, should try to establish tunnel.
5285 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175286 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5287 "Host: www.example.org:443\r\n"
5288 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205289
rsleevidb16bb02015-11-12 23:47:175290 MockWrite("GET /1 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
rsleevidb16bb02015-11-12 23:47:175294 MockWrite("GET /2 HTTP/1.1\r\n"
5295 "Host: www.example.org\r\n"
5296 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205297 };
5298
5299 // The proxy responds to the connect with a 407, using a persistent
5300 // connection.
5301 MockRead data_reads1[] = {
5302 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5303
5304 MockRead("HTTP/1.1 200 OK\r\n"),
5305 MockRead("Content-Length: 1\r\n\r\n"),
5306 MockRead(SYNCHRONOUS, "1"),
5307
5308 MockRead("HTTP/1.1 200 OK\r\n"),
5309 MockRead("Content-Length: 2\r\n\r\n"),
5310 MockRead(SYNCHRONOUS, "22"),
5311 };
5312
Ryan Sleevib8d7ea02018-05-07 20:01:015313 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075314 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205315 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075316 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205317
5318 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585319 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195320 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205321
5322 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015323 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205324
5325 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015326 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205327
5328 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525329 ASSERT_TRUE(response1);
5330 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205331 EXPECT_EQ(1, response1->headers->GetContentLength());
5332
5333 LoadTimingInfo load_timing_info1;
5334 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5335 TestLoadTimingNotReusedWithPac(load_timing_info1,
5336 CONNECT_TIMING_HAS_SSL_TIMES);
5337
5338 trans1.reset();
5339
5340 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585341 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195342 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205343
5344 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015345 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205346
5347 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015348 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205349
5350 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525351 ASSERT_TRUE(response2);
5352 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205353 EXPECT_EQ(2, response2->headers->GetContentLength());
5354
5355 LoadTimingInfo load_timing_info2;
5356 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5357 TestLoadTimingReusedWithPac(load_timing_info2);
5358
5359 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5360
5361 trans2.reset();
5362 session->CloseAllConnections();
5363}
5364
[email protected]2df19bb2010-08-25 20:13:465365// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015366TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275367 HttpRequestInfo request;
5368 request.method = "GET";
bncce36dca22015-04-21 22:11:235369 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105370 request.traffic_annotation =
5371 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275372
[email protected]2df19bb2010-08-25 20:13:465373 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495374 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5375 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515376 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075377 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095378 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465379
[email protected]2df19bb2010-08-25 20:13:465380 // Since we have proxy, should use full url
5381 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235382 MockWrite(
5383 "GET http://www.example.org/ HTTP/1.1\r\n"
5384 "Host: www.example.org\r\n"
5385 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465386 };
5387
5388 MockRead data_reads1[] = {
5389 MockRead("HTTP/1.1 200 OK\r\n"),
5390 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5391 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065392 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465393 };
5394
Ryan Sleevib8d7ea02018-05-07 20:01:015395 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075396 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065397 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075398 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465399
[email protected]49639fa2011-12-20 23:22:415400 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465401
bnc691fda62016-08-12 00:43:165402 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505403
bnc691fda62016-08-12 00:43:165404 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015405 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465406
5407 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015408 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465409
[email protected]58e32bb2013-01-21 18:23:255410 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165411 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255412 TestLoadTimingNotReused(load_timing_info,
5413 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5414
bnc691fda62016-08-12 00:43:165415 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525416 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465417
tbansal2ecbbc72016-10-06 17:15:475418 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465419 EXPECT_TRUE(response->headers->IsKeepAlive());
5420 EXPECT_EQ(200, response->headers->response_code());
5421 EXPECT_EQ(100, response->headers->GetContentLength());
5422 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5423
5424 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525425 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465426}
5427
[email protected]7642b5ae2010-09-01 20:55:175428// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015429TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275430 HttpRequestInfo request;
5431 request.method = "GET";
bncce36dca22015-04-21 22:11:235432 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105433 request.traffic_annotation =
5434 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275435
[email protected]7642b5ae2010-09-01 20:55:175436 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495437 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5438 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515439 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075440 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095441 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175442
bncce36dca22015-04-21 22:11:235443 // fetch http://www.example.org/ via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135444 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455445 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415446 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175447
Ryan Hamilton0239aac2018-05-19 00:03:135448 spdy::SpdySerializedFrame resp(
5449 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5450 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175451 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415452 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175453 };
5454
Ryan Sleevib8d7ea02018-05-07 20:01:015455 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075456 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175457
[email protected]8ddf8322012-02-23 18:08:065458 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365459 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075460 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175461
[email protected]49639fa2011-12-20 23:22:415462 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175463
bnc691fda62016-08-12 00:43:165464 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505465
bnc691fda62016-08-12 00:43:165466 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175468
5469 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015470 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175471
[email protected]58e32bb2013-01-21 18:23:255472 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165473 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255474 TestLoadTimingNotReused(load_timing_info,
5475 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5476
bnc691fda62016-08-12 00:43:165477 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525478 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475479 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525480 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025481 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175482
5483 std::string response_data;
bnc691fda62016-08-12 00:43:165484 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235485 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175486}
5487
[email protected]1c173852014-06-19 12:51:505488// Verifies that a session which races and wins against the owning transaction
5489// (completing prior to host resolution), doesn't fail the transaction.
5490// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015491TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505492 HttpRequestInfo request;
5493 request.method = "GET";
bncce36dca22015-04-21 22:11:235494 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105495 request.traffic_annotation =
5496 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505497
5498 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495499 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5500 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515501 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505502 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095503 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505504
bncce36dca22015-04-21 22:11:235505 // Fetch http://www.example.org/ through the SPDY proxy.
Ryan Hamilton0239aac2018-05-19 00:03:135506 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455507 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415508 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505509
Raul Tambre94493c652019-03-11 17:18:355510 spdy::SpdySerializedFrame resp(
5511 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135512 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505513 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415514 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505515 };
5516
Ryan Sleevib8d7ea02018-05-07 20:01:015517 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]1c173852014-06-19 12:51:505518 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5519
5520 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365521 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505522 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5523
5524 TestCompletionCallback callback1;
5525
bnc691fda62016-08-12 00:43:165526 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505527
5528 // Stall the hostname resolution begun by the transaction.
[email protected]1c173852014-06-19 12:51:505529 session_deps_.host_resolver->set_ondemand_mode(true);
5530
bnc691fda62016-08-12 00:43:165531 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015532 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505533
5534 // Race a session to the proxy, which completes first.
5535 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045536 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:115537 PRIVACY_MODE_DISABLED,
5538 SpdySessionKey::IsProxySession::kTrue, SocketTag());
[email protected]1c173852014-06-19 12:51:505539 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525540 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505541
5542 // Unstall the resolution begun by the transaction.
5543 session_deps_.host_resolver->set_ondemand_mode(true);
5544 session_deps_.host_resolver->ResolveAllPending();
5545
5546 EXPECT_FALSE(callback1.have_result());
5547 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015548 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505549
bnc691fda62016-08-12 00:43:165550 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525551 ASSERT_TRUE(response);
5552 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025553 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505554
5555 std::string response_data;
bnc691fda62016-08-12 00:43:165556 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505557 EXPECT_EQ(kUploadData, response_data);
5558}
5559
[email protected]dc7bd1c52010-11-12 00:01:135560// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015561TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275562 HttpRequestInfo request;
5563 request.method = "GET";
bncce36dca22015-04-21 22:11:235564 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105565 request.traffic_annotation =
5566 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275567
[email protected]79cb5c12011-09-12 13:12:045568 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495569 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5570 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515571 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075572 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095573 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135574
[email protected]dc7bd1c52010-11-12 00:01:135575 // The first request will be a bare GET, the second request will be a
5576 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455577 spdy_util_.set_default_url(request.url);
Ryan Hamilton0239aac2018-05-19 00:03:135578 spdy::SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485579 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385580 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135581 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465582 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135583 };
Ryan Hamilton0239aac2018-05-19 00:03:135584 spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
Avi Drissman4365a4782018-12-28 19:26:245585 kExtraAuthorizationHeaders, base::size(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485586 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135587 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415588 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135589 };
5590
5591 // The first response is a 407 proxy authentication challenge, and the second
5592 // response will be a 200 response since the second request includes a valid
5593 // Authorization header.
5594 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465595 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135596 };
Ryan Hamilton0239aac2018-05-19 00:03:135597 spdy::SpdySerializedFrame resp_authentication(
5598 spdy_util_.ConstructSpdyReplyError(
5599 "407", kExtraAuthenticationHeaders,
Avi Drissman4365a4782018-12-28 19:26:245600 base::size(kExtraAuthenticationHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135601 spdy::SpdySerializedFrame body_authentication(
bncdf80d44fd2016-07-15 20:27:415602 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:135603 spdy::SpdySerializedFrame resp_data(
Raul Tambre94493c652019-03-11 17:18:355604 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:135605 spdy::SpdySerializedFrame body_data(
5606 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135607 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415608 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465609 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415610 CreateMockRead(resp_data, 4),
5611 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135612 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135613 };
5614
Ryan Sleevib8d7ea02018-05-07 20:01:015615 SequencedSocketData data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075616 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135617
[email protected]8ddf8322012-02-23 18:08:065618 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365619 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075620 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135621
[email protected]49639fa2011-12-20 23:22:415622 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135623
bnc691fda62016-08-12 00:43:165624 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135625
bnc691fda62016-08-12 00:43:165626 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015627 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135628
5629 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015630 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135631
bnc691fda62016-08-12 00:43:165632 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135633
wezca1070932016-05-26 20:30:525634 ASSERT_TRUE(response);
5635 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135636 EXPECT_EQ(407, response->headers->response_code());
5637 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435638 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135639
[email protected]49639fa2011-12-20 23:22:415640 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135641
bnc691fda62016-08-12 00:43:165642 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135644
5645 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015646 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135647
bnc691fda62016-08-12 00:43:165648 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135649
wezca1070932016-05-26 20:30:525650 ASSERT_TRUE(response_restart);
5651 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135652 EXPECT_EQ(200, response_restart->headers->response_code());
5653 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525654 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135655}
5656
[email protected]d9da5fe2010-10-13 22:37:165657// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015658TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275659 HttpRequestInfo request;
5660 request.method = "GET";
bncce36dca22015-04-21 22:11:235661 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105662 request.traffic_annotation =
5663 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275664
[email protected]d9da5fe2010-10-13 22:37:165665 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495666 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5667 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515668 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075669 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095670 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165671
bnc691fda62016-08-12 00:43:165672 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165673
bncce36dca22015-04-21 22:11:235674 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135675 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045676 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5677 HostPortPair("www.example.org", 443)));
bncce36dca22015-04-21 22:11:235678 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165679
bncce36dca22015-04-21 22:11:235680 const char get[] =
5681 "GET / HTTP/1.1\r\n"
5682 "Host: www.example.org\r\n"
5683 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135684 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195685 spdy_util_.ConstructSpdyDataFrame(1, get, false));
Ryan Hamilton0239aac2018-05-19 00:03:135686 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:355687 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165688 const char resp[] = "HTTP/1.1 200 OK\r\n"
5689 "Content-Length: 10\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135690 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195691 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:135692 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195693 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
Ryan Hamilton0239aac2018-05-19 00:03:135694 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415695 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045696
5697 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415698 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5699 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045700 };
5701
[email protected]d9da5fe2010-10-13 22:37:165702 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415703 CreateMockRead(conn_resp, 1, ASYNC),
5704 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5705 CreateMockRead(wrapped_body, 4, ASYNC),
5706 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135707 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165708 };
5709
Ryan Sleevib8d7ea02018-05-07 20:01:015710 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075711 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165712
[email protected]8ddf8322012-02-23 18:08:065713 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365714 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075715 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065716 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075717 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165718
[email protected]49639fa2011-12-20 23:22:415719 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165720
bnc691fda62016-08-12 00:43:165721 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015722 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165723
5724 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015725 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165726
[email protected]58e32bb2013-01-21 18:23:255727 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165728 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255729 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5730
bnc691fda62016-08-12 00:43:165731 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525732 ASSERT_TRUE(response);
5733 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165734 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5735
5736 std::string response_data;
bnc691fda62016-08-12 00:43:165737 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165738 EXPECT_EQ("1234567890", response_data);
5739}
5740
5741// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015742TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5743 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385744
[email protected]cb9bf6ca2011-01-28 13:15:275745 HttpRequestInfo request;
5746 request.method = "GET";
bncce36dca22015-04-21 22:11:235747 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105748 request.traffic_annotation =
5749 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275750
[email protected]d9da5fe2010-10-13 22:37:165751 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495752 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5753 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515754 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075755 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095756 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165757
bnc691fda62016-08-12 00:43:165758 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165759
bncce36dca22015-04-21 22:11:235760 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135761 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045762 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5763 HostPortPair("www.example.org", 443)));
bncce36dca22015-04-21 22:11:235764 // fetch https://www.example.org/ via SPDY
5765 const char kMyUrl[] = "https://www.example.org/";
Ryan Hamilton0239aac2018-05-19 00:03:135766 spdy::SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495767 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:135768 spdy::SpdySerializedFrame wrapped_get(
5769 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
5770 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:355771 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135772 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:355773 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135774 spdy::SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025775 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135776 spdy::SpdySerializedFrame body(
5777 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5778 spdy::SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025779 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135780 spdy::SpdySerializedFrame window_update_get_resp(
bncdf80d44fd2016-07-15 20:27:415781 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
Ryan Hamilton0239aac2018-05-19 00:03:135782 spdy::SpdySerializedFrame window_update_body(
bncdf80d44fd2016-07-15 20:27:415783 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045784
5785 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415786 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5787 CreateMockWrite(window_update_get_resp, 6),
5788 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045789 };
5790
[email protected]d9da5fe2010-10-13 22:37:165791 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415792 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095793 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415794 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5795 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135796 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165797 };
5798
Ryan Sleevib8d7ea02018-05-07 20:01:015799 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075800 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165801
[email protected]8ddf8322012-02-23 18:08:065802 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365803 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075804 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065805 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365806 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075807 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165808
[email protected]49639fa2011-12-20 23:22:415809 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165810
bnc691fda62016-08-12 00:43:165811 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015812 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165813
rch32320842015-05-16 15:57:095814 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555815 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095816 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595817 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165818 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015819 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165820
[email protected]58e32bb2013-01-21 18:23:255821 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165822 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255823 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5824
bnc691fda62016-08-12 00:43:165825 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525826 ASSERT_TRUE(response);
5827 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025828 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165829
5830 std::string response_data;
bnc691fda62016-08-12 00:43:165831 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235832 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165833}
5834
5835// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015836TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275837 HttpRequestInfo request;
5838 request.method = "GET";
bncce36dca22015-04-21 22:11:235839 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105840 request.traffic_annotation =
5841 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275842
[email protected]d9da5fe2010-10-13 22:37:165843 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495844 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5845 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515846 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075847 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095848 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165849
bnc691fda62016-08-12 00:43:165850 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165851
bncce36dca22015-04-21 22:11:235852 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135853 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045854 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5855 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135856 spdy::SpdySerializedFrame get(
5857 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165858
5859 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415860 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165861 };
5862
Ryan Hamilton0239aac2018-05-19 00:03:135863 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
5864 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165865 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415866 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165867 };
5868
Ryan Sleevib8d7ea02018-05-07 20:01:015869 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075870 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165871
[email protected]8ddf8322012-02-23 18:08:065872 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365873 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065875 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365876 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075877 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165878
[email protected]49639fa2011-12-20 23:22:415879 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165880
bnc691fda62016-08-12 00:43:165881 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015882 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165883
5884 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015885 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165886
ttuttle960fcbf2016-04-19 13:26:325887 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165888}
5889
Matt Menkecb2cd0982018-12-19 17:54:045890// Test the case where a proxied H2 session doesn't exist when an auth challenge
5891// is observed, but does exist by the time auth credentials are provided.
5892// Proxy-Connection: Close is used so that there's a second DNS lookup, which is
5893// what causes the existing H2 session to be noticed and reused.
5894TEST_F(HttpNetworkTransactionTest, ProxiedH2SessionAppearsDuringAuth) {
5895 ProxyConfig proxy_config;
5896 proxy_config.set_auto_detect(true);
5897 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
5898
5899 CapturingProxyResolver capturing_proxy_resolver;
5900 capturing_proxy_resolver.set_proxy_server(
5901 ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 70)));
5902 session_deps_.proxy_resolution_service =
5903 std::make_unique<ProxyResolutionService>(
5904 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
5905 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
5906 std::make_unique<CapturingProxyResolverFactory>(
5907 &capturing_proxy_resolver),
5908 nullptr);
5909
5910 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5911
5912 const char kMyUrl[] = "https://www.example.org/";
5913 spdy::SpdySerializedFrame get(spdy_util_.ConstructSpdyGet(kMyUrl, 1, LOWEST));
5914 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:355915 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menkecb2cd0982018-12-19 17:54:045916 spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
5917
5918 spdy_util_.UpdateWithStreamDestruction(1);
5919 spdy::SpdySerializedFrame get2(
5920 spdy_util_.ConstructSpdyGet(kMyUrl, 3, LOWEST));
5921 spdy::SpdySerializedFrame get_resp2(
Raul Tambre94493c652019-03-11 17:18:355922 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Matt Menkecb2cd0982018-12-19 17:54:045923 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
5924
5925 MockWrite auth_challenge_writes[] = {
5926 MockWrite(ASYNC, 0,
5927 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5928 "Host: www.example.org:443\r\n"
5929 "Proxy-Connection: keep-alive\r\n\r\n"),
5930 };
5931
5932 MockRead auth_challenge_reads[] = {
5933 MockRead(ASYNC, 1,
5934 "HTTP/1.1 407 Authentication Required\r\n"
5935 "Content-Length: 0\r\n"
5936 "Proxy-Connection: close\r\n"
5937 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
5938 };
5939
5940 MockWrite spdy_writes[] = {
5941 MockWrite(ASYNC, 0,
5942 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5943 "Host: www.example.org:443\r\n"
5944 "Proxy-Connection: keep-alive\r\n"
5945 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5946 CreateMockWrite(get, 2),
5947 CreateMockWrite(get2, 5),
5948 };
5949
5950 MockRead spdy_reads[] = {
5951 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
5952 CreateMockRead(get_resp, 3, ASYNC),
5953 CreateMockRead(body, 4, ASYNC),
5954 CreateMockRead(get_resp2, 6, ASYNC),
5955 CreateMockRead(body2, 7, ASYNC),
5956
5957 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 8),
5958 };
5959
5960 SequencedSocketData auth_challenge1(auth_challenge_reads,
5961 auth_challenge_writes);
5962 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge1);
5963
5964 SequencedSocketData auth_challenge2(auth_challenge_reads,
5965 auth_challenge_writes);
5966 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge2);
5967
5968 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
5969 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5970
5971 SSLSocketDataProvider ssl(ASYNC, OK);
5972 ssl.next_proto = kProtoHTTP2;
5973 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5974
5975 TestCompletionCallback callback;
5976 std::string response_data;
5977
5978 // Run first request until an auth challenge is observed.
5979 HttpRequestInfo request1;
5980 request1.method = "GET";
5981 request1.url = GURL(kMyUrl);
5982 request1.traffic_annotation =
5983 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5984 HttpNetworkTransaction trans1(LOWEST, session.get());
5985 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
5986 EXPECT_THAT(callback.GetResult(rv), IsOk());
5987 const HttpResponseInfo* response = trans1.GetResponseInfo();
5988 ASSERT_TRUE(response);
5989 ASSERT_TRUE(response->headers);
5990 EXPECT_EQ(407, response->headers->response_code());
5991 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5992 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
5993
5994 // Run second request until an auth challenge is observed.
5995 HttpRequestInfo request2;
5996 request2.method = "GET";
5997 request2.url = GURL(kMyUrl);
5998 request2.traffic_annotation =
5999 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6000 HttpNetworkTransaction trans2(LOWEST, session.get());
6001 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6002 EXPECT_THAT(callback.GetResult(rv), IsOk());
6003 response = trans2.GetResponseInfo();
6004 ASSERT_TRUE(response);
6005 ASSERT_TRUE(response->headers);
6006 EXPECT_EQ(407, response->headers->response_code());
6007 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6008 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6009
6010 // Now provide credentials for the first request, and wait for it to complete.
6011 rv = trans1.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6012 rv = callback.GetResult(rv);
6013 EXPECT_THAT(rv, IsOk());
6014 response = trans1.GetResponseInfo();
6015 ASSERT_TRUE(response);
6016 ASSERT_TRUE(response->headers);
6017 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6018 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6019 EXPECT_EQ(kUploadData, response_data);
6020
6021 // Now provide credentials for the second request. It should notice the
6022 // existing session, and reuse it.
6023 rv = trans2.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6024 EXPECT_THAT(callback.GetResult(rv), IsOk());
6025 response = trans2.GetResponseInfo();
6026 ASSERT_TRUE(response);
6027 ASSERT_TRUE(response->headers);
6028 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6029 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6030 EXPECT_EQ(kUploadData, response_data);
6031}
6032
[email protected]f6c63db52013-02-02 00:35:226033// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6034// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:016035TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226036 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
6037 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496038 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6039 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516040 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076041 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096042 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506043 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226044
6045 HttpRequestInfo request1;
6046 request1.method = "GET";
bncce36dca22015-04-21 22:11:236047 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226048 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106049 request1.traffic_annotation =
6050 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226051
6052 HttpRequestInfo request2;
6053 request2.method = "GET";
bncce36dca22015-04-21 22:11:236054 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226055 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106056 request2.traffic_annotation =
6057 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226058
bncce36dca22015-04-21 22:11:236059 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136060 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046061 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6062 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136063 spdy::SpdySerializedFrame conn_resp1(
Raul Tambre94493c652019-03-11 17:18:356064 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226065
bncce36dca22015-04-21 22:11:236066 // Fetch https://www.example.org/ via HTTP.
6067 const char get1[] =
6068 "GET / HTTP/1.1\r\n"
6069 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226070 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136071 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196072 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226073 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6074 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136075 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196076 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136077 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196078 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136079 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416080 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226081
bncce36dca22015-04-21 22:11:236082 // CONNECT to mail.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136083 spdy::SpdyHeaderBlock connect2_block;
6084 connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
6085 connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
6086 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
Matt Menke6e879bd2019-03-18 17:26:046087 3, std::move(connect2_block), HttpProxyConnectJob::kH2QuicTunnelPriority,
6088 false));
[email protected]601e03f12014-04-06 16:26:396089
Ryan Hamilton0239aac2018-05-19 00:03:136090 spdy::SpdySerializedFrame conn_resp2(
Raul Tambre94493c652019-03-11 17:18:356091 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
[email protected]f6c63db52013-02-02 00:35:226092
bncce36dca22015-04-21 22:11:236093 // Fetch https://mail.example.org/ via HTTP.
6094 const char get2[] =
6095 "GET / HTTP/1.1\r\n"
6096 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226097 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136098 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196099 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:226100 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6101 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136102 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196103 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136104 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196105 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:226106
6107 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416108 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6109 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:226110 };
6111
6112 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416113 CreateMockRead(conn_resp1, 1, ASYNC),
6114 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
6115 CreateMockRead(wrapped_body1, 4, ASYNC),
6116 CreateMockRead(conn_resp2, 6, ASYNC),
6117 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
6118 CreateMockRead(wrapped_body2, 9, ASYNC),
6119 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:226120 };
6121
Ryan Sleevib8d7ea02018-05-07 20:01:016122 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506123 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226124
6125 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366126 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506127 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226128 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506129 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226130 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506131 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:226132
6133 TestCompletionCallback callback;
6134
bnc691fda62016-08-12 00:43:166135 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206136 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016137 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226138
6139 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166140 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:226141 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6142
bnc691fda62016-08-12 00:43:166143 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526144 ASSERT_TRUE(response);
6145 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226146 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6147
6148 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446149 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
bnc691fda62016-08-12 00:43:166150 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506151 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226152
bnc691fda62016-08-12 00:43:166153 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206154 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016155 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226156
6157 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166158 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226159 // Even though the SPDY connection is reused, a new tunnelled connection has
6160 // to be created, so the socket's load timing looks like a fresh connection.
6161 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
6162
6163 // The requests should have different IDs, since they each are using their own
6164 // separate stream.
6165 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6166
bnc691fda62016-08-12 00:43:166167 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506168 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226169}
6170
6171// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6172// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:016173TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226174 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
6175 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496176 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6177 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516178 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076179 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096180 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506181 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226182
6183 HttpRequestInfo request1;
6184 request1.method = "GET";
bncce36dca22015-04-21 22:11:236185 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226186 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106187 request1.traffic_annotation =
6188 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226189
6190 HttpRequestInfo request2;
6191 request2.method = "GET";
bncce36dca22015-04-21 22:11:236192 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:226193 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106194 request2.traffic_annotation =
6195 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226196
bncce36dca22015-04-21 22:11:236197 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136198 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046199 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6200 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136201 spdy::SpdySerializedFrame conn_resp1(
Raul Tambre94493c652019-03-11 17:18:356202 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226203
bncce36dca22015-04-21 22:11:236204 // Fetch https://www.example.org/ via HTTP.
6205 const char get1[] =
6206 "GET / HTTP/1.1\r\n"
6207 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226208 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136209 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196210 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226211 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6212 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136213 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196214 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136215 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196216 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136217 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416218 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226219
bncce36dca22015-04-21 22:11:236220 // Fetch https://www.example.org/2 via HTTP.
6221 const char get2[] =
6222 "GET /2 HTTP/1.1\r\n"
6223 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226224 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136225 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196226 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:226227 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6228 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136229 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196230 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136231 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196232 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:226233
6234 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416235 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6236 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:226237 };
6238
6239 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416240 CreateMockRead(conn_resp1, 1, ASYNC),
6241 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:466242 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416243 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:466244 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416245 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:226246 };
6247
Ryan Sleevib8d7ea02018-05-07 20:01:016248 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506249 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226250
6251 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366252 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506253 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226254 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506255 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226256
6257 TestCompletionCallback callback;
6258
bnc87dcefc2017-05-25 12:47:586259 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196260 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206261 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016262 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226263
6264 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016265 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226266
6267 LoadTimingInfo load_timing_info;
6268 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6269 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6270
6271 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526272 ASSERT_TRUE(response);
6273 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226274 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6275
6276 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446277 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
[email protected]90499482013-06-01 00:39:506278 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226279 trans.reset();
6280
bnc87dcefc2017-05-25 12:47:586281 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:196282 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206283 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016284 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226285
[email protected]f6c63db52013-02-02 00:35:226286 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016287 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226288
6289 LoadTimingInfo load_timing_info2;
6290 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
6291 TestLoadTimingReused(load_timing_info2);
6292
6293 // The requests should have the same ID.
6294 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6295
[email protected]90499482013-06-01 00:39:506296 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226297}
6298
6299// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
6300// Proxy to different servers.
bncd16676a2016-07-20 16:23:016301TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:226302 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496303 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6304 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516305 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076306 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096307 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506308 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226309
6310 HttpRequestInfo request1;
6311 request1.method = "GET";
bncce36dca22015-04-21 22:11:236312 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226313 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106314 request1.traffic_annotation =
6315 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226316
6317 HttpRequestInfo request2;
6318 request2.method = "GET";
bncce36dca22015-04-21 22:11:236319 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226320 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106321 request2.traffic_annotation =
6322 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226323
bncce36dca22015-04-21 22:11:236324 // http://www.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136325 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:236326 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136327 spdy::SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:156328 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136329 spdy::SpdySerializedFrame get_resp1(
Raul Tambre94493c652019-03-11 17:18:356330 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:136331 spdy::SpdySerializedFrame body1(
6332 spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:386333 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:226334
bncce36dca22015-04-21 22:11:236335 // http://mail.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136336 spdy::SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:236337 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136338 spdy::SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:156339 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136340 spdy::SpdySerializedFrame get_resp2(
Raul Tambre94493c652019-03-11 17:18:356341 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:136342 spdy::SpdySerializedFrame body2(
6343 spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:226344
6345 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416346 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:226347 };
6348
6349 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416350 CreateMockRead(get_resp1, 1, ASYNC),
6351 CreateMockRead(body1, 2, ASYNC),
6352 CreateMockRead(get_resp2, 4, ASYNC),
6353 CreateMockRead(body2, 5, ASYNC),
6354 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:226355 };
6356
Ryan Sleevib8d7ea02018-05-07 20:01:016357 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506358 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226359
6360 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366361 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226363
6364 TestCompletionCallback callback;
6365
bnc87dcefc2017-05-25 12:47:586366 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196367 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206368 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016369 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226370
6371 LoadTimingInfo load_timing_info;
6372 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6373 TestLoadTimingNotReused(load_timing_info,
6374 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6375
6376 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526377 ASSERT_TRUE(response);
6378 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:026379 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:226380
6381 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446382 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
mmenke11eb5152015-06-09 14:50:506383 rv = trans->Read(buf.get(), 256, callback.callback());
6384 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226385 // Delete the first request, so the second one can reuse the socket.
6386 trans.reset();
6387
bnc691fda62016-08-12 00:43:166388 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206389 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016390 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226391
6392 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166393 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226394 TestLoadTimingReused(load_timing_info2);
6395
6396 // The requests should have the same ID.
6397 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6398
bnc691fda62016-08-12 00:43:166399 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506400 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226401}
6402
Matt Menke2436b2f2018-12-11 18:07:116403// Test that an HTTP/2 CONNECT through an HTTPS Proxy to a HTTP/2 server and a
6404// direct (non-proxied) request to the proxy server are not pooled, as that
6405// would break socket pool isolation.
6406TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation1) {
6407 ProxyConfig proxy_config;
6408 proxy_config.set_auto_detect(true);
6409 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6410
6411 CapturingProxyResolver capturing_proxy_resolver;
6412 session_deps_.proxy_resolution_service =
6413 std::make_unique<ProxyResolutionService>(
6414 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6415 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6416 std::make_unique<CapturingProxyResolverFactory>(
6417 &capturing_proxy_resolver),
6418 nullptr);
6419
6420 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6421
6422 SpdyTestUtil spdy_util1;
6423 // CONNECT to www.example.org:443 via HTTP/2.
6424 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046425 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6426 HostPortPair("www.example.org", 443)));
Matt Menke2436b2f2018-12-11 18:07:116427 // fetch https://www.example.org/ via HTTP/2.
6428 const char kMyUrl[] = "https://www.example.org/";
6429 spdy::SpdySerializedFrame get(spdy_util1.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6430 spdy::SpdySerializedFrame wrapped_get(
6431 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6432 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:356433 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menke2436b2f2018-12-11 18:07:116434 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:356435 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menke2436b2f2018-12-11 18:07:116436 spdy::SpdySerializedFrame wrapped_get_resp(
6437 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6438 spdy::SpdySerializedFrame body(spdy_util1.ConstructSpdyDataFrame(1, true));
6439 spdy::SpdySerializedFrame wrapped_body(
6440 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6441 spdy::SpdySerializedFrame window_update_get_resp(
6442 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6443 spdy::SpdySerializedFrame window_update_body(
6444 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6445
6446 MockWrite spdy_writes1[] = {
6447 CreateMockWrite(connect, 0),
6448 CreateMockWrite(wrapped_get, 2),
6449 CreateMockWrite(window_update_get_resp, 6),
6450 CreateMockWrite(window_update_body, 7),
6451 };
6452
6453 MockRead spdy_reads1[] = {
6454 CreateMockRead(conn_resp, 1, ASYNC),
6455 MockRead(ASYNC, ERR_IO_PENDING, 3),
6456 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6457 CreateMockRead(wrapped_body, 5, ASYNC),
6458 MockRead(ASYNC, 0, 8),
6459 };
6460
6461 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6462 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6463
6464 // Fetch https://proxy:70/ via HTTP/2. Needs a new SpdyTestUtil, since it uses
6465 // a new pipe.
6466 SpdyTestUtil spdy_util2;
6467 spdy::SpdySerializedFrame req(
6468 spdy_util2.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6469 MockWrite spdy_writes2[] = {CreateMockWrite(req, 0)};
6470
6471 spdy::SpdySerializedFrame resp(
6472 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6473 spdy::SpdySerializedFrame data(spdy_util2.ConstructSpdyDataFrame(1, true));
6474 MockRead spdy_reads2[] = {
6475 CreateMockRead(resp, 1),
6476 CreateMockRead(data, 2),
6477 MockRead(ASYNC, 0, 3),
6478 };
6479 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6480 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6481
6482 SSLSocketDataProvider ssl(ASYNC, OK);
6483 ssl.next_proto = kProtoHTTP2;
6484 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6485 SSLSocketDataProvider ssl2(ASYNC, OK);
6486 ssl2.next_proto = kProtoHTTP2;
6487 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6488 SSLSocketDataProvider ssl3(ASYNC, OK);
6489 ssl3.next_proto = kProtoHTTP2;
6490 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6491
6492 TestCompletionCallback callback;
6493 std::string response_data;
6494
6495 // Make a request using proxy:70 as a HTTP/2 proxy.
6496 capturing_proxy_resolver.set_proxy_server(
6497 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6498 HttpRequestInfo request1;
6499 request1.method = "GET";
6500 request1.url = GURL("https://www.example.org/");
6501 request1.traffic_annotation =
6502 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6503
6504 HttpNetworkTransaction trans1(LOWEST, session.get());
6505 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
6506 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6507
6508 // Allow the SpdyProxyClientSocket's write callback to complete.
6509 base::RunLoop().RunUntilIdle();
6510 // Now allow the read of the response to complete.
6511 spdy_data1.Resume();
6512 rv = callback.WaitForResult();
6513 EXPECT_THAT(rv, IsOk());
6514
6515 const HttpResponseInfo* response = trans1.GetResponseInfo();
6516 ASSERT_TRUE(response);
6517 ASSERT_TRUE(response->headers);
6518 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6519
6520 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6521 EXPECT_EQ(kUploadData, response_data);
6522 RunUntilIdle();
6523
6524 // Make a direct HTTP/2 request to proxy:70.
6525 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6526 HttpRequestInfo request2;
6527 request2.method = "GET";
6528 request2.url = GURL("https://proxy:70/");
6529 request2.traffic_annotation =
6530 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6531 HttpNetworkTransaction trans2(LOWEST, session.get());
6532 EXPECT_THAT(callback.GetResult(trans2.Start(&request2, callback.callback(),
6533 NetLogWithSource())),
6534 IsOk());
6535 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6536}
6537
6538// Same as above, but reverse request order, since the code to check for an
6539// existing session is different for tunnels and direct connections.
6540TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation2) {
6541 // Configure against https proxy server "myproxy:80".
6542 ProxyConfig proxy_config;
6543 proxy_config.set_auto_detect(true);
6544 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6545
6546 CapturingProxyResolver capturing_proxy_resolver;
6547 session_deps_.proxy_resolution_service =
6548 std::make_unique<ProxyResolutionService>(
6549 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6550 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6551 std::make_unique<CapturingProxyResolverFactory>(
6552 &capturing_proxy_resolver),
6553 nullptr);
6554
6555 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6556 // Fetch https://proxy:70/ via HTTP/2.
6557 SpdyTestUtil spdy_util1;
6558 spdy::SpdySerializedFrame req(
6559 spdy_util1.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6560 MockWrite spdy_writes1[] = {CreateMockWrite(req, 0)};
6561
6562 spdy::SpdySerializedFrame resp(
6563 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
6564 spdy::SpdySerializedFrame data(spdy_util1.ConstructSpdyDataFrame(1, true));
6565 MockRead spdy_reads1[] = {
6566 CreateMockRead(resp, 1),
6567 CreateMockRead(data, 2),
6568 MockRead(ASYNC, 0, 3),
6569 };
6570 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6571 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6572
6573 SpdyTestUtil spdy_util2;
6574 // CONNECT to www.example.org:443 via HTTP/2.
6575 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046576 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6577 HostPortPair("www.example.org", 443)));
Matt Menke2436b2f2018-12-11 18:07:116578 // fetch https://www.example.org/ via HTTP/2.
6579 const char kMyUrl[] = "https://www.example.org/";
6580 spdy::SpdySerializedFrame get(spdy_util2.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6581 spdy::SpdySerializedFrame wrapped_get(
6582 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6583 spdy::SpdySerializedFrame conn_resp(
6584 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6585 spdy::SpdySerializedFrame get_resp(
6586 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6587 spdy::SpdySerializedFrame wrapped_get_resp(
6588 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6589 spdy::SpdySerializedFrame body(spdy_util2.ConstructSpdyDataFrame(1, true));
6590 spdy::SpdySerializedFrame wrapped_body(
6591 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6592 spdy::SpdySerializedFrame window_update_get_resp(
6593 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6594 spdy::SpdySerializedFrame window_update_body(
6595 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6596
6597 MockWrite spdy_writes2[] = {
6598 CreateMockWrite(connect, 0),
6599 CreateMockWrite(wrapped_get, 2),
6600 CreateMockWrite(window_update_get_resp, 6),
6601 CreateMockWrite(window_update_body, 7),
6602 };
6603
6604 MockRead spdy_reads2[] = {
6605 CreateMockRead(conn_resp, 1, ASYNC),
6606 MockRead(ASYNC, ERR_IO_PENDING, 3),
6607 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6608 CreateMockRead(wrapped_body, 5, ASYNC),
6609 MockRead(ASYNC, 0, 8),
6610 };
6611
6612 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6613 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6614
6615 SSLSocketDataProvider ssl(ASYNC, OK);
6616 ssl.next_proto = kProtoHTTP2;
6617 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6618 SSLSocketDataProvider ssl2(ASYNC, OK);
6619 ssl2.next_proto = kProtoHTTP2;
6620 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6621 SSLSocketDataProvider ssl3(ASYNC, OK);
6622 ssl3.next_proto = kProtoHTTP2;
6623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6624
6625 TestCompletionCallback callback;
6626 std::string response_data;
6627
6628 // Make a direct HTTP/2 request to proxy:70.
6629 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6630 HttpRequestInfo request1;
6631 request1.method = "GET";
6632 request1.url = GURL("https://proxy:70/");
6633 request1.traffic_annotation =
6634 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6635 HttpNetworkTransaction trans1(LOWEST, session.get());
6636 EXPECT_THAT(callback.GetResult(trans1.Start(&request1, callback.callback(),
6637 NetLogWithSource())),
6638 IsOk());
6639 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6640 RunUntilIdle();
6641
6642 // Make a request using proxy:70 as a HTTP/2 proxy.
6643 capturing_proxy_resolver.set_proxy_server(
6644 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6645 HttpRequestInfo request2;
6646 request2.method = "GET";
6647 request2.url = GURL("https://www.example.org/");
6648 request2.traffic_annotation =
6649 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6650
6651 HttpNetworkTransaction trans2(LOWEST, session.get());
6652 int rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6653 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6654
6655 // Allow the SpdyProxyClientSocket's write callback to complete.
6656 base::RunLoop().RunUntilIdle();
6657 // Now allow the read of the response to complete.
6658 spdy_data2.Resume();
6659 rv = callback.WaitForResult();
6660 EXPECT_THAT(rv, IsOk());
6661
6662 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
6663 ASSERT_TRUE(response2);
6664 ASSERT_TRUE(response2->headers);
6665 EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
6666
6667 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6668 EXPECT_EQ(kUploadData, response_data);
6669}
6670
[email protected]2df19bb2010-08-25 20:13:466671// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:016672TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:466673 HttpRequestInfo request;
6674 request.method = "GET";
bncce36dca22015-04-21 22:11:236675 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466676 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296677 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:106678 request.traffic_annotation =
6679 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:466680
[email protected]79cb5c12011-09-12 13:12:046681 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496682 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6683 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516684 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076685 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096686 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276687
[email protected]2df19bb2010-08-25 20:13:466688 // Since we have proxy, should use full url
6689 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:166690 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6691 "Host: www.example.org\r\n"
6692 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466693
bnc691fda62016-08-12 00:43:166694 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:236695 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:166696 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6697 "Host: www.example.org\r\n"
6698 "Proxy-Connection: keep-alive\r\n"
6699 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466700 };
6701
6702 // The proxy responds to the GET with a 407, using a persistent
6703 // connection.
6704 MockRead data_reads1[] = {
6705 // No credentials.
6706 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6707 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6708 MockRead("Proxy-Connection: keep-alive\r\n"),
6709 MockRead("Content-Length: 0\r\n\r\n"),
6710
6711 MockRead("HTTP/1.1 200 OK\r\n"),
6712 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6713 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066714 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466715 };
6716
Ryan Sleevib8d7ea02018-05-07 20:01:016717 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:076718 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:066719 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076720 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466721
[email protected]49639fa2011-12-20 23:22:416722 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:466723
bnc691fda62016-08-12 00:43:166724 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506725
bnc691fda62016-08-12 00:43:166726 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:016727 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466728
6729 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016730 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466731
[email protected]58e32bb2013-01-21 18:23:256732 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166733 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256734 TestLoadTimingNotReused(load_timing_info,
6735 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6736
bnc691fda62016-08-12 00:43:166737 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526738 ASSERT_TRUE(response);
6739 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:466740 EXPECT_EQ(407, response->headers->response_code());
6741 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:436742 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:466743
[email protected]49639fa2011-12-20 23:22:416744 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:466745
bnc691fda62016-08-12 00:43:166746 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466748
6749 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016750 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466751
[email protected]58e32bb2013-01-21 18:23:256752 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:166753 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256754 // Retrying with HTTP AUTH is considered to be reusing a socket.
6755 TestLoadTimingReused(load_timing_info);
6756
bnc691fda62016-08-12 00:43:166757 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526758 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:466759
6760 EXPECT_TRUE(response->headers->IsKeepAlive());
6761 EXPECT_EQ(200, response->headers->response_code());
6762 EXPECT_EQ(100, response->headers->GetContentLength());
6763 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6764
6765 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:526766 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:466767}
6768
[email protected]23e482282013-06-14 16:08:026769void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086770 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426771 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086772 request.method = "GET";
bncce36dca22015-04-21 22:11:236773 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106774 request.traffic_annotation =
6775 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086776
[email protected]cb9bf6ca2011-01-28 13:15:276777 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496778 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6779 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276781
[email protected]c744cf22009-02-27 07:28:086782 // Since we have proxy, should try to establish tunnel.
6783 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176784 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6785 "Host: www.example.org:443\r\n"
6786 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086787 };
6788
6789 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236790 status, MockRead("Content-Length: 10\r\n\r\n"),
6791 // No response body because the test stops reading here.
6792 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086793 };
6794
Ryan Sleevib8d7ea02018-05-07 20:01:016795 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:076796 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086797
[email protected]49639fa2011-12-20 23:22:416798 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086799
bnc691fda62016-08-12 00:43:166800 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506801
tfarina42834112016-09-22 13:38:206802 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016803 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086804
6805 rv = callback.WaitForResult();
6806 EXPECT_EQ(expected_status, rv);
6807}
6808
[email protected]23e482282013-06-14 16:08:026809void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236810 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086811 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426812 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086813}
6814
bncd16676a2016-07-20 16:23:016815TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086816 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6817}
6818
bncd16676a2016-07-20 16:23:016819TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086820 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6821}
6822
bncd16676a2016-07-20 16:23:016823TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086824 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6825}
6826
bncd16676a2016-07-20 16:23:016827TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086828 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6829}
6830
bncd16676a2016-07-20 16:23:016831TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086832 ConnectStatusHelper(
6833 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6834}
6835
bncd16676a2016-07-20 16:23:016836TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086837 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6838}
6839
bncd16676a2016-07-20 16:23:016840TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086841 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6842}
6843
bncd16676a2016-07-20 16:23:016844TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086845 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6846}
6847
bncd16676a2016-07-20 16:23:016848TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086849 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6850}
6851
bncd16676a2016-07-20 16:23:016852TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086853 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6854}
6855
bncd16676a2016-07-20 16:23:016856TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086857 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6858}
6859
bncd16676a2016-07-20 16:23:016860TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086861 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6862}
6863
bncd16676a2016-07-20 16:23:016864TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086865 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6866}
6867
bncd16676a2016-07-20 16:23:016868TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086869 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6870}
6871
bncd16676a2016-07-20 16:23:016872TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086873 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6874}
6875
bncd16676a2016-07-20 16:23:016876TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086877 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6878}
6879
bncd16676a2016-07-20 16:23:016880TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376881 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6882}
6883
bncd16676a2016-07-20 16:23:016884TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086885 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6886}
6887
bncd16676a2016-07-20 16:23:016888TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086889 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6890}
6891
bncd16676a2016-07-20 16:23:016892TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086893 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6894}
6895
bncd16676a2016-07-20 16:23:016896TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086897 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6898}
6899
bncd16676a2016-07-20 16:23:016900TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086901 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6902}
6903
bncd16676a2016-07-20 16:23:016904TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086905 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6906}
6907
bncd16676a2016-07-20 16:23:016908TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086909 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6910}
6911
bncd16676a2016-07-20 16:23:016912TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086913 ConnectStatusHelperWithExpectedStatus(
6914 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546915 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086916}
6917
bncd16676a2016-07-20 16:23:016918TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086919 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6920}
6921
bncd16676a2016-07-20 16:23:016922TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086923 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6924}
6925
bncd16676a2016-07-20 16:23:016926TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086927 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6928}
6929
bncd16676a2016-07-20 16:23:016930TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086931 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6932}
6933
bncd16676a2016-07-20 16:23:016934TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086935 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6936}
6937
bncd16676a2016-07-20 16:23:016938TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086939 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6940}
6941
bncd16676a2016-07-20 16:23:016942TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086943 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6944}
6945
bncd16676a2016-07-20 16:23:016946TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086947 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6948}
6949
bncd16676a2016-07-20 16:23:016950TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086951 ConnectStatusHelper(
6952 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6953}
6954
bncd16676a2016-07-20 16:23:016955TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086956 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6957}
6958
bncd16676a2016-07-20 16:23:016959TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086960 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6961}
6962
bncd16676a2016-07-20 16:23:016963TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086964 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6965}
6966
bncd16676a2016-07-20 16:23:016967TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086968 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6969}
6970
bncd16676a2016-07-20 16:23:016971TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086972 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6973}
6974
bncd16676a2016-07-20 16:23:016975TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086976 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6977}
6978
bncd16676a2016-07-20 16:23:016979TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086980 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6981}
6982
[email protected]038e9a32008-10-08 22:40:166983// Test the flow when both the proxy server AND origin server require
6984// authentication. Again, this uses basic auth for both since that is
6985// the simplest to mock.
bncd16676a2016-07-20 16:23:016986TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276987 HttpRequestInfo request;
6988 request.method = "GET";
bncce36dca22015-04-21 22:11:236989 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106990 request.traffic_annotation =
6991 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276992
[email protected]038e9a32008-10-08 22:40:166993 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496994 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6995 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096996 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076997
bnc691fda62016-08-12 00:43:166998 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166999
[email protected]f9ee6b52008-11-08 06:46:237000 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237001 MockWrite(
7002 "GET http://www.example.org/ HTTP/1.1\r\n"
7003 "Host: www.example.org\r\n"
7004 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237005 };
7006
[email protected]038e9a32008-10-08 22:40:167007 MockRead data_reads1[] = {
7008 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
7009 // Give a couple authenticate options (only the middle one is actually
7010 // supported).
[email protected]22927ad2009-09-21 19:56:197011 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:167012 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7013 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
7014 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7015 // Large content-length -- won't matter, as connection will be reset.
7016 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067017 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:167018 };
7019
bnc691fda62016-08-12 00:43:167020 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:167021 // request we should be issuing -- the final header line contains the
7022 // proxy's credentials.
7023 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237024 MockWrite(
7025 "GET http://www.example.org/ HTTP/1.1\r\n"
7026 "Host: www.example.org\r\n"
7027 "Proxy-Connection: keep-alive\r\n"
7028 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167029 };
7030
7031 // Now the proxy server lets the request pass through to origin server.
7032 // The origin server responds with a 401.
7033 MockRead data_reads2[] = {
7034 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7035 // Note: We are using the same realm-name as the proxy server. This is
7036 // completely valid, as realms are unique across hosts.
7037 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7038 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7039 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067040 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:167041 };
7042
bnc691fda62016-08-12 00:43:167043 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:167044 // the credentials for both the proxy and origin server.
7045 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237046 MockWrite(
7047 "GET http://www.example.org/ HTTP/1.1\r\n"
7048 "Host: www.example.org\r\n"
7049 "Proxy-Connection: keep-alive\r\n"
7050 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
7051 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167052 };
7053
7054 // Lastly we get the desired content.
7055 MockRead data_reads3[] = {
7056 MockRead("HTTP/1.0 200 OK\r\n"),
7057 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7058 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067059 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:167060 };
7061
Ryan Sleevib8d7ea02018-05-07 20:01:017062 StaticSocketDataProvider data1(data_reads1, data_writes1);
7063 StaticSocketDataProvider data2(data_reads2, data_writes2);
7064 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077065 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7066 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7067 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:167068
[email protected]49639fa2011-12-20 23:22:417069 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:167070
tfarina42834112016-09-22 13:38:207071 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017072 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167073
7074 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017075 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167076
bnc691fda62016-08-12 00:43:167077 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527078 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047079 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167080
[email protected]49639fa2011-12-20 23:22:417081 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:167082
bnc691fda62016-08-12 00:43:167083 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:017084 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167085
7086 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017087 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167088
bnc691fda62016-08-12 00:43:167089 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527090 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047091 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:167092
[email protected]49639fa2011-12-20 23:22:417093 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:167094
bnc691fda62016-08-12 00:43:167095 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7096 callback3.callback());
robpercival214763f2016-07-01 23:27:017097 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167098
7099 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017100 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167101
bnc691fda62016-08-12 00:43:167102 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527103 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:167104 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:167105}
[email protected]4ddaf2502008-10-23 18:26:197106
[email protected]ea9dc9a2009-09-05 00:43:327107// For the NTLM implementation using SSPI, we skip the NTLM tests since we
7108// can't hook into its internals to cause it to generate predictable NTLM
7109// authorization headers.
7110#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377111// The NTLM authentication unit tests are based on known test data from the
7112// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
7113// flow rather than the implementation of the NTLM protocol. See net/ntlm
7114// for the implementation and testing of the protocol.
7115//
7116// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:297117
7118// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557119TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:427120 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:247121 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557122 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:107123 request.traffic_annotation =
7124 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547125
7126 // Ensure load is not disrupted by flags which suppress behaviour specific
7127 // to other auth schemes.
7128 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:247129
Zentaro Kavanagh6ccee512017-09-28 18:34:097130 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7131 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097132 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277133
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377134 // Generate the NTLM messages based on known test data.
7135 std::string negotiate_msg;
7136 std::string challenge_msg;
7137 std::string authenticate_msg;
7138 base::Base64Encode(
7139 base::StringPiece(
7140 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247141 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377142 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557143 base::Base64Encode(
7144 base::StringPiece(
7145 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247146 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557147 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377148 base::Base64Encode(
7149 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097150 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557151 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247152 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557153 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377154 &authenticate_msg);
7155
[email protected]3f918782009-02-28 01:29:247156 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557157 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7158 "Host: server\r\n"
7159 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247160 };
7161
7162 MockRead data_reads1[] = {
7163 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047164 // Negotiate and NTLM are often requested together. However, we only want
7165 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7166 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:247167 MockRead("WWW-Authenticate: NTLM\r\n"),
7168 MockRead("Connection: close\r\n"),
7169 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367170 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247171 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:247172 };
7173
7174 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167175 // After restarting with a null identity, this is the
7176 // request we should be issuing -- the final header line contains a Type
7177 // 1 message.
7178 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557179 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167180 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377181 "Authorization: NTLM "),
7182 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247183
bnc691fda62016-08-12 00:43:167184 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377185 // (using correct credentials). The second request continues on the
7186 // same connection.
bnc691fda62016-08-12 00:43:167187 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557188 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167189 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377190 "Authorization: NTLM "),
7191 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247192 };
7193
7194 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:027195 // The origin server responds with a Type 2 message.
7196 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377197 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7198 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027199 MockRead("Content-Type: text/html\r\n\r\n"),
7200 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:247201
Bence Béky1e4ef192017-09-18 19:58:027202 // Lastly we get the desired content.
7203 MockRead("HTTP/1.1 200 OK\r\n"),
7204 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7205 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:247206 };
7207
Ryan Sleevib8d7ea02018-05-07 20:01:017208 StaticSocketDataProvider data1(data_reads1, data_writes1);
7209 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077210 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7211 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:247212
Bence Béky83eb3512017-09-05 12:56:097213 SSLSocketDataProvider ssl1(ASYNC, OK);
7214 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7215 SSLSocketDataProvider ssl2(ASYNC, OK);
7216 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7217
[email protected]49639fa2011-12-20 23:22:417218 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:247219
bnc691fda62016-08-12 00:43:167220 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507221
tfarina42834112016-09-22 13:38:207222 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017223 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247224
7225 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017226 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247227
bnc691fda62016-08-12 00:43:167228 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227229
bnc691fda62016-08-12 00:43:167230 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527231 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047232 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:247233
[email protected]49639fa2011-12-20 23:22:417234 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:257235
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377236 rv = trans.RestartWithAuth(
7237 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7238 callback2.callback());
robpercival214763f2016-07-01 23:27:017239 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257240
7241 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017242 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257243
bnc691fda62016-08-12 00:43:167244 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257245
bnc691fda62016-08-12 00:43:167246 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527247 ASSERT_TRUE(response);
7248 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:257249
[email protected]49639fa2011-12-20 23:22:417250 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:247251
bnc691fda62016-08-12 00:43:167252 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017253 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247254
[email protected]0757e7702009-03-27 04:00:227255 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017256 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247257
bnc691fda62016-08-12 00:43:167258 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527259 ASSERT_TRUE(response);
7260 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027261 EXPECT_EQ(14, response->headers->GetContentLength());
7262
7263 std::string response_data;
7264 rv = ReadTransaction(&trans, &response_data);
7265 EXPECT_THAT(rv, IsOk());
7266 EXPECT_EQ("Please Login\r\n", response_data);
7267
7268 EXPECT_TRUE(data1.AllReadDataConsumed());
7269 EXPECT_TRUE(data1.AllWriteDataConsumed());
7270 EXPECT_TRUE(data2.AllReadDataConsumed());
7271 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:247272}
7273
[email protected]385a4672009-03-11 22:21:297274// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557275TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:427276 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:297277 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557278 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:107279 request.traffic_annotation =
7280 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:297281
Zentaro Kavanagh6ccee512017-09-28 18:34:097282 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7283 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097284 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277285
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377286 // Generate the NTLM messages based on known test data.
7287 std::string negotiate_msg;
7288 std::string challenge_msg;
7289 std::string authenticate_msg;
7290 base::Base64Encode(
7291 base::StringPiece(
7292 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247293 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377294 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557295 base::Base64Encode(
7296 base::StringPiece(
7297 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247298 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557299 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377300 base::Base64Encode(
7301 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097302 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557303 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247304 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557305 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377306 &authenticate_msg);
7307
7308 // The authenticate message when |kWrongPassword| is sent.
7309 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557310 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
7311 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
7312 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
7313 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
7314 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
7315 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377316
Zentaro Kavanagh1890a3d2018-01-29 19:52:557317 // Sanity check that it's the same length as the correct authenticate message
7318 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377319 ASSERT_EQ(authenticate_msg.length(),
7320 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:557321 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377322
[email protected]385a4672009-03-11 22:21:297323 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557324 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7325 "Host: server\r\n"
7326 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297327 };
7328
7329 MockRead data_reads1[] = {
7330 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047331 // Negotiate and NTLM are often requested together. However, we only want
7332 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7333 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:297334 MockRead("WWW-Authenticate: NTLM\r\n"),
7335 MockRead("Connection: close\r\n"),
7336 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367337 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297338 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297339 };
7340
7341 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167342 // After restarting with a null identity, this is the
7343 // request we should be issuing -- the final header line contains a Type
7344 // 1 message.
7345 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557346 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167347 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377348 "Authorization: NTLM "),
7349 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297350
bnc691fda62016-08-12 00:43:167351 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377352 // (using incorrect credentials). The second request continues on the
7353 // same connection.
bnc691fda62016-08-12 00:43:167354 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557355 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167356 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377357 "Authorization: NTLM "),
7358 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297359 };
7360
7361 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377362 // The origin server responds with a Type 2 message.
7363 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7364 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7365 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
7366 MockRead("Content-Type: text/html\r\n\r\n"),
7367 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297368
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377369 // Wrong password.
7370 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7371 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
7372 MockRead("Content-Length: 42\r\n"),
7373 MockRead("Content-Type: text/html\r\n\r\n"),
7374 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297375 };
7376
7377 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:167378 // After restarting with a null identity, this is the
7379 // request we should be issuing -- the final header line contains a Type
7380 // 1 message.
7381 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557382 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167383 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377384 "Authorization: NTLM "),
7385 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297386
bnc691fda62016-08-12 00:43:167387 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7388 // (the credentials for the origin server). The second request continues
7389 // on the same connection.
7390 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557391 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167392 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377393 "Authorization: NTLM "),
7394 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297395 };
7396
7397 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:027398 // The origin server responds with a Type 2 message.
7399 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377400 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7401 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027402 MockRead("Content-Type: text/html\r\n\r\n"),
7403 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297404
Bence Béky1e4ef192017-09-18 19:58:027405 // Lastly we get the desired content.
7406 MockRead("HTTP/1.1 200 OK\r\n"),
7407 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7408 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:297409 };
7410
Ryan Sleevib8d7ea02018-05-07 20:01:017411 StaticSocketDataProvider data1(data_reads1, data_writes1);
7412 StaticSocketDataProvider data2(data_reads2, data_writes2);
7413 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077414 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7415 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7416 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:297417
Bence Béky83eb3512017-09-05 12:56:097418 SSLSocketDataProvider ssl1(ASYNC, OK);
7419 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7420 SSLSocketDataProvider ssl2(ASYNC, OK);
7421 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7422 SSLSocketDataProvider ssl3(ASYNC, OK);
7423 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
7424
[email protected]49639fa2011-12-20 23:22:417425 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:297426
bnc691fda62016-08-12 00:43:167427 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507428
tfarina42834112016-09-22 13:38:207429 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017430 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297431
7432 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017433 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297434
bnc691fda62016-08-12 00:43:167435 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:297436
bnc691fda62016-08-12 00:43:167437 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527438 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047439 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:297440
[email protected]49639fa2011-12-20 23:22:417441 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:297442
[email protected]0757e7702009-03-27 04:00:227443 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377444 rv = trans.RestartWithAuth(
7445 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
7446 callback2.callback());
robpercival214763f2016-07-01 23:27:017447 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297448
[email protected]10af5fe72011-01-31 16:17:257449 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017450 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297451
bnc691fda62016-08-12 00:43:167452 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417453 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167454 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257456 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017457 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167458 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227459
bnc691fda62016-08-12 00:43:167460 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527461 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047462 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:227463
[email protected]49639fa2011-12-20 23:22:417464 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:227465
7466 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377467 rv = trans.RestartWithAuth(
7468 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7469 callback4.callback());
robpercival214763f2016-07-01 23:27:017470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257471
7472 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:017473 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257474
bnc691fda62016-08-12 00:43:167475 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257476
[email protected]49639fa2011-12-20 23:22:417477 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:257478
7479 // One more roundtrip
bnc691fda62016-08-12 00:43:167480 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:017481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227482
7483 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:017484 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:227485
bnc691fda62016-08-12 00:43:167486 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527487 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027488 EXPECT_EQ(14, response->headers->GetContentLength());
7489
7490 std::string response_data;
7491 rv = ReadTransaction(&trans, &response_data);
7492 EXPECT_THAT(rv, IsOk());
7493 EXPECT_EQ("Please Login\r\n", response_data);
7494
7495 EXPECT_TRUE(data1.AllReadDataConsumed());
7496 EXPECT_TRUE(data1.AllWriteDataConsumed());
7497 EXPECT_TRUE(data2.AllReadDataConsumed());
7498 EXPECT_TRUE(data2.AllWriteDataConsumed());
7499 EXPECT_TRUE(data3.AllReadDataConsumed());
7500 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:297501}
Bence Béky83eb3512017-09-05 12:56:097502
Bence Béky3238f2e12017-09-22 22:44:497503// Server requests NTLM authentication, which is not supported over HTTP/2.
7504// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:097505TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:097506 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7507 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:097508
Zentaro Kavanagh1890a3d2018-01-29 19:52:557509 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:097510
7511 HttpRequestInfo request;
7512 request.method = "GET";
7513 request.url = GURL(kUrl);
Ramin Halavatib5e433e62018-02-07 07:41:107514 request.traffic_annotation =
7515 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:097516
7517 // First request without credentials.
Ryan Hamilton0239aac2018-05-19 00:03:137518 spdy::SpdyHeaderBlock request_headers0(
7519 spdy_util_.ConstructGetHeaderBlock(kUrl));
7520 spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
Bence Béky83eb3512017-09-05 12:56:097521 1, std::move(request_headers0), LOWEST, true));
7522
Ryan Hamilton0239aac2018-05-19 00:03:137523 spdy::SpdyHeaderBlock response_headers0;
7524 response_headers0[spdy::kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:097525 response_headers0["www-authenticate"] = "NTLM";
Ryan Hamilton0239aac2018-05-19 00:03:137526 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Béky83eb3512017-09-05 12:56:097527 1, std::move(response_headers0), true));
7528
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377529 // Stream 1 is closed.
7530 spdy_util_.UpdateWithStreamDestruction(1);
7531
7532 // Generate the NTLM messages based on known test data.
7533 std::string negotiate_msg;
7534 std::string challenge_msg;
7535 std::string authenticate_msg;
7536 base::Base64Encode(
7537 base::StringPiece(
7538 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247539 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377540 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557541 base::Base64Encode(
7542 base::StringPiece(
7543 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247544 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557545 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377546 base::Base64Encode(
7547 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097548 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557549 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247550 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557551 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377552 &authenticate_msg);
7553
7554 // Retry with authorization header.
Ryan Hamilton0239aac2018-05-19 00:03:137555 spdy::SpdyHeaderBlock request_headers1(
7556 spdy_util_.ConstructGetHeaderBlock(kUrl));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377557 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
Ryan Hamilton0239aac2018-05-19 00:03:137558 spdy::SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377559 3, std::move(request_headers1), LOWEST, true));
7560
Ryan Hamilton0239aac2018-05-19 00:03:137561 spdy::SpdySerializedFrame rst(
7562 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377563
Bence Béky3238f2e12017-09-22 22:44:497564 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
7565 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:097566
7567 // Retry yet again using HTTP/1.1.
7568 MockWrite writes1[] = {
7569 // After restarting with a null identity, this is the
7570 // request we should be issuing -- the final header line contains a Type
7571 // 1 message.
7572 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557573 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097574 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377575 "Authorization: NTLM "),
7576 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097577
7578 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7579 // (the credentials for the origin server). The second request continues
7580 // on the same connection.
7581 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557582 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097583 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377584 "Authorization: NTLM "),
7585 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097586 };
7587
7588 MockRead reads1[] = {
7589 // The origin server responds with a Type 2 message.
7590 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377591 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7592 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:097593 MockRead("Content-Type: text/html\r\n\r\n"),
7594 MockRead("You are not authorized to view this page\r\n"),
7595
7596 // Lastly we get the desired content.
7597 MockRead("HTTP/1.1 200 OK\r\n"),
7598 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027599 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:097600 };
Ryan Sleevib8d7ea02018-05-07 20:01:017601 SequencedSocketData data0(reads0, writes0);
7602 StaticSocketDataProvider data1(reads1, writes1);
Bence Béky83eb3512017-09-05 12:56:097603 session_deps_.socket_factory->AddSocketDataProvider(&data0);
7604 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7605
7606 SSLSocketDataProvider ssl0(ASYNC, OK);
7607 ssl0.next_proto = kProtoHTTP2;
7608 SSLSocketDataProvider ssl1(ASYNC, OK);
7609 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
7610 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7611
7612 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7613 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7614
7615 TestCompletionCallback callback1;
7616 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
7617 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7618
7619 rv = callback1.WaitForResult();
7620 EXPECT_THAT(rv, IsOk());
7621
7622 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7623
7624 const HttpResponseInfo* response = trans.GetResponseInfo();
7625 ASSERT_TRUE(response);
7626 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
7627
7628 TestCompletionCallback callback2;
7629
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377630 rv = trans.RestartWithAuth(
7631 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7632 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:097633 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7634
7635 rv = callback2.WaitForResult();
7636 EXPECT_THAT(rv, IsOk());
7637
7638 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7639
7640 response = trans.GetResponseInfo();
7641 ASSERT_TRUE(response);
7642 EXPECT_FALSE(response->auth_challenge);
7643
7644 TestCompletionCallback callback3;
7645
7646 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
7647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7648
7649 rv = callback3.WaitForResult();
7650 EXPECT_THAT(rv, IsOk());
7651
7652 response = trans.GetResponseInfo();
7653 ASSERT_TRUE(response);
7654 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:027655 EXPECT_EQ(14, response->headers->GetContentLength());
7656
7657 std::string response_data;
7658 rv = ReadTransaction(&trans, &response_data);
7659 EXPECT_THAT(rv, IsOk());
7660 EXPECT_EQ("Please Login\r\n", response_data);
7661
7662 EXPECT_TRUE(data0.AllReadDataConsumed());
7663 EXPECT_TRUE(data0.AllWriteDataConsumed());
7664 EXPECT_TRUE(data1.AllReadDataConsumed());
7665 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:097666}
David Benjamin5cb91132018-04-06 05:54:497667
7668// Test that, if we have an NTLM proxy and the origin resets the connection, we
7669// do no retry forever checking for TLS version interference. This is a
7670// regression test for https://crbug.com/823387.
7671TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
7672 // The NTLM test data expects the proxy to be named 'server'. The origin is
7673 // https://origin/.
7674 session_deps_.proxy_resolution_service =
7675 ProxyResolutionService::CreateFixedFromPacResult(
7676 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
7677
7678 SSLConfig config;
David Benjamin5cb91132018-04-06 05:54:497679 session_deps_.ssl_config_service =
Ryan Sleevib8449e02018-07-15 04:31:077680 std::make_unique<TestSSLConfigService>(config);
David Benjamin5cb91132018-04-06 05:54:497681
7682 HttpRequestInfo request;
7683 request.method = "GET";
7684 request.url = GURL("https://origin/");
7685 request.traffic_annotation =
7686 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7687
7688 // Ensure load is not disrupted by flags which suppress behaviour specific
7689 // to other auth schemes.
7690 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7691
7692 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7693 MockGetMSTime, MockGenerateRandom, MockGetHostName);
7694 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7695
7696 // Generate the NTLM messages based on known test data.
7697 std::string negotiate_msg;
7698 std::string challenge_msg;
7699 std::string authenticate_msg;
7700 base::Base64Encode(
7701 base::StringPiece(
7702 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247703 base::size(ntlm::test::kExpectedNegotiateMsg)),
David Benjamin5cb91132018-04-06 05:54:497704 &negotiate_msg);
7705 base::Base64Encode(
7706 base::StringPiece(
7707 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247708 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
David Benjamin5cb91132018-04-06 05:54:497709 &challenge_msg);
7710 base::Base64Encode(
7711 base::StringPiece(
7712 reinterpret_cast<const char*>(
7713 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247714 base::size(
David Benjamin5cb91132018-04-06 05:54:497715 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
7716 &authenticate_msg);
7717
7718 MockWrite data_writes[] = {
7719 // The initial CONNECT request.
7720 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7721 "Host: origin:443\r\n"
7722 "Proxy-Connection: keep-alive\r\n\r\n"),
7723
7724 // After restarting with an identity.
7725 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7726 "Host: origin:443\r\n"
7727 "Proxy-Connection: keep-alive\r\n"
7728 "Proxy-Authorization: NTLM "),
7729 MockWrite(negotiate_msg.c_str()),
7730 // End headers.
7731 MockWrite("\r\n\r\n"),
7732
7733 // The second restart.
7734 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7735 "Host: origin:443\r\n"
7736 "Proxy-Connection: keep-alive\r\n"
7737 "Proxy-Authorization: NTLM "),
7738 MockWrite(authenticate_msg.c_str()),
7739 // End headers.
7740 MockWrite("\r\n\r\n"),
7741 };
7742
7743 MockRead data_reads[] = {
7744 // The initial NTLM response.
7745 MockRead("HTTP/1.1 407 Access Denied\r\n"
7746 "Content-Length: 0\r\n"
7747 "Proxy-Authenticate: NTLM\r\n\r\n"),
7748
7749 // The NTLM challenge message.
7750 MockRead("HTTP/1.1 407 Access Denied\r\n"
7751 "Content-Length: 0\r\n"
7752 "Proxy-Authenticate: NTLM "),
7753 MockRead(challenge_msg.c_str()),
7754 // End headers.
7755 MockRead("\r\n\r\n"),
7756
7757 // Finally the tunnel is established.
7758 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
7759 };
7760
Ryan Sleevib8d7ea02018-05-07 20:01:017761 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497762 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
Ryan Sleevib8d7ea02018-05-07 20:01:017763 StaticSocketDataProvider data2(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497764 SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
Steven Valdez0ef94d02018-11-19 23:28:137765 data_ssl2.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
David Benjamin5cb91132018-04-06 05:54:497766 session_deps_.socket_factory->AddSocketDataProvider(&data);
7767 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
7768 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7769 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
7770
7771 // Start the transaction. The proxy responds with an NTLM authentication
7772 // request.
7773 TestCompletionCallback callback;
7774 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7775 int rv = callback.GetResult(
7776 trans.Start(&request, callback.callback(), NetLogWithSource()));
7777
7778 EXPECT_THAT(rv, IsOk());
7779 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7780 const HttpResponseInfo* response = trans.GetResponseInfo();
7781 ASSERT_TRUE(response);
7782 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get()));
7783
7784 // Configure credentials. The proxy responds with the challenge message.
7785 rv = callback.GetResult(trans.RestartWithAuth(
7786 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7787 callback.callback()));
7788 EXPECT_THAT(rv, IsOk());
7789 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7790 response = trans.GetResponseInfo();
7791 ASSERT_TRUE(response);
7792 EXPECT_FALSE(response->auth_challenge);
7793
7794 // Restart once more. The tunnel will be established and the the SSL handshake
7795 // will reset. The TLS 1.3 version interference probe will then kick in and
7796 // restart the process. The proxy responds with another NTLM authentiation
7797 // request, but we don't need to provide credentials as the cached ones work/
7798 rv = callback.GetResult(
7799 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7800 EXPECT_THAT(rv, IsOk());
7801 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7802 response = trans.GetResponseInfo();
7803 ASSERT_TRUE(response);
7804 EXPECT_FALSE(response->auth_challenge);
7805
7806 // The proxy responds with the NTLM challenge message.
7807 rv = callback.GetResult(
7808 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7809 EXPECT_THAT(rv, IsOk());
7810 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7811 response = trans.GetResponseInfo();
7812 ASSERT_TRUE(response);
7813 EXPECT_FALSE(response->auth_challenge);
7814
7815 // Send the NTLM authenticate message. The tunnel is established and the
7816 // handshake resets again. We should not retry again.
7817 rv = callback.GetResult(
7818 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7819 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
7820}
7821
[email protected]ea9dc9a2009-09-05 00:43:327822#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:297823
[email protected]4ddaf2502008-10-23 18:26:197824// Test reading a server response which has only headers, and no body.
7825// After some maximum number of bytes is consumed, the transaction should
7826// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:017827TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:427828 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:197829 request.method = "GET";
bncce36dca22015-04-21 22:11:237830 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107831 request.traffic_annotation =
7832 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:197833
danakj1fd259a02016-04-16 03:17:097834 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167835 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277836
[email protected]b75b7b2f2009-10-06 00:54:537837 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:437838 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:537839 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:197840
7841 MockRead data_reads[] = {
7842 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:067843 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:197844 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:067845 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:197846 };
Ryan Sleevib8d7ea02018-05-07 20:01:017847 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077848 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:197849
[email protected]49639fa2011-12-20 23:22:417850 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:197851
tfarina42834112016-09-22 13:38:207852 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017853 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:197854
7855 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017856 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197857}
[email protected]f4e426b2008-11-05 00:24:497858
7859// Make sure that we don't try to reuse a TCPClientSocket when failing to
7860// establish tunnel.
7861// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017862TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277863 HttpRequestInfo request;
7864 request.method = "GET";
bncce36dca22015-04-21 22:11:237865 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107866 request.traffic_annotation =
7867 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277868
[email protected]f4e426b2008-11-05 00:24:497869 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497870 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7871 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017872
danakj1fd259a02016-04-16 03:17:097873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497874
bnc87dcefc2017-05-25 12:47:587875 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197876 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497877
[email protected]f4e426b2008-11-05 00:24:497878 // Since we have proxy, should try to establish tunnel.
7879 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177880 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7881 "Host: www.example.org:443\r\n"
7882 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497883 };
7884
[email protected]77848d12008-11-14 00:00:227885 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497886 // connection. Usually a proxy would return 501 (not implemented),
7887 // or 200 (tunnel established).
7888 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237889 MockRead("HTTP/1.1 404 Not Found\r\n"),
7890 MockRead("Content-Length: 10\r\n\r\n"),
7891 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497892 };
7893
Ryan Sleevib8d7ea02018-05-07 20:01:017894 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:077895 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497896
[email protected]49639fa2011-12-20 23:22:417897 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497898
tfarina42834112016-09-22 13:38:207899 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017900 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497901
7902 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017903 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497904
[email protected]b4404c02009-04-10 16:38:527905 // Empty the current queue. This is necessary because idle sockets are
7906 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557907 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527908
[email protected]f4e426b2008-11-05 00:24:497909 // We now check to make sure the TCPClientSocket was not added back to
7910 // the pool.
[email protected]90499482013-06-01 00:39:507911 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497912 trans.reset();
fdoray92e35a72016-06-10 15:54:557913 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497914 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507915 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497916}
[email protected]372d34a2008-11-05 21:30:517917
[email protected]1b157c02009-04-21 01:55:407918// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017919TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427920 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407921 request.method = "GET";
bncce36dca22015-04-21 22:11:237922 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107923 request.traffic_annotation =
7924 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407925
danakj1fd259a02016-04-16 03:17:097926 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277927
bnc691fda62016-08-12 00:43:167928 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277929
[email protected]1b157c02009-04-21 01:55:407930 MockRead data_reads[] = {
7931 // A part of the response body is received with the response headers.
7932 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7933 // The rest of the response body is received in two parts.
7934 MockRead("lo"),
7935 MockRead(" world"),
7936 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067937 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407938 };
7939
Ryan Sleevib8d7ea02018-05-07 20:01:017940 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077941 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407942
[email protected]49639fa2011-12-20 23:22:417943 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407944
tfarina42834112016-09-22 13:38:207945 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017946 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407947
7948 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017949 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407950
bnc691fda62016-08-12 00:43:167951 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527952 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407953
wezca1070932016-05-26 20:30:527954 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407955 std::string status_line = response->headers->GetStatusLine();
7956 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7957
[email protected]90499482013-06-01 00:39:507958 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407959
7960 std::string response_data;
bnc691fda62016-08-12 00:43:167961 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017962 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407963 EXPECT_EQ("hello world", response_data);
7964
7965 // Empty the current queue. This is necessary because idle sockets are
7966 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557967 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407968
7969 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507970 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407971}
7972
[email protected]76a505b2010-08-25 06:23:007973// Make sure that we recycle a SSL socket after reading all of the response
7974// body.
bncd16676a2016-07-20 16:23:017975TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007976 HttpRequestInfo request;
7977 request.method = "GET";
bncce36dca22015-04-21 22:11:237978 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107979 request.traffic_annotation =
7980 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007981
7982 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237983 MockWrite(
7984 "GET / HTTP/1.1\r\n"
7985 "Host: www.example.org\r\n"
7986 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007987 };
7988
7989 MockRead data_reads[] = {
7990 MockRead("HTTP/1.1 200 OK\r\n"),
7991 MockRead("Content-Length: 11\r\n\r\n"),
7992 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067993 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007994 };
7995
[email protected]8ddf8322012-02-23 18:08:067996 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077997 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007998
Ryan Sleevib8d7ea02018-05-07 20:01:017999 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078000 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:008001
[email protected]49639fa2011-12-20 23:22:418002 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008003
danakj1fd259a02016-04-16 03:17:098004 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168005 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008006
tfarina42834112016-09-22 13:38:208007 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008008
robpercival214763f2016-07-01 23:27:018009 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8010 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008011
bnc691fda62016-08-12 00:43:168012 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528013 ASSERT_TRUE(response);
8014 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008015 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8016
[email protected]90499482013-06-01 00:39:508017 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008018
8019 std::string response_data;
bnc691fda62016-08-12 00:43:168020 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018021 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008022 EXPECT_EQ("hello world", response_data);
8023
8024 // Empty the current queue. This is necessary because idle sockets are
8025 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558026 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008027
8028 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238029 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008030}
8031
8032// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
8033// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:018034TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:008035 HttpRequestInfo request;
8036 request.method = "GET";
bncce36dca22015-04-21 22:11:238037 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108038 request.traffic_annotation =
8039 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:008040
8041 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238042 MockWrite(
8043 "GET / HTTP/1.1\r\n"
8044 "Host: www.example.org\r\n"
8045 "Connection: keep-alive\r\n\r\n"),
8046 MockWrite(
8047 "GET / HTTP/1.1\r\n"
8048 "Host: www.example.org\r\n"
8049 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:008050 };
8051
8052 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:428053 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8054 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:008055
[email protected]8ddf8322012-02-23 18:08:068056 SSLSocketDataProvider ssl(ASYNC, OK);
8057 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078058 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8059 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:008060
Ryan Sleevib8d7ea02018-05-07 20:01:018061 StaticSocketDataProvider data(data_reads, data_writes);
8062 StaticSocketDataProvider data2(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078063 session_deps_.socket_factory->AddSocketDataProvider(&data);
8064 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:008065
[email protected]49639fa2011-12-20 23:22:418066 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008067
danakj1fd259a02016-04-16 03:17:098068 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:588069 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198070 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008071
tfarina42834112016-09-22 13:38:208072 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008073
robpercival214763f2016-07-01 23:27:018074 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8075 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008076
8077 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528078 ASSERT_TRUE(response);
8079 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008080 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8081
[email protected]90499482013-06-01 00:39:508082 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008083
8084 std::string response_data;
8085 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018086 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008087 EXPECT_EQ("hello world", response_data);
8088
8089 // Empty the current queue. This is necessary because idle sockets are
8090 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558091 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008092
8093 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238094 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008095
8096 // Now start the second transaction, which should reuse the previous socket.
8097
bnc87dcefc2017-05-25 12:47:588098 trans =
Jeremy Roman0579ed62017-08-29 15:56:198099 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008100
tfarina42834112016-09-22 13:38:208101 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008102
robpercival214763f2016-07-01 23:27:018103 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8104 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008105
8106 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528107 ASSERT_TRUE(response);
8108 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008109 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8110
[email protected]90499482013-06-01 00:39:508111 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008112
8113 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018114 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008115 EXPECT_EQ("hello world", response_data);
8116
8117 // Empty the current queue. This is necessary because idle sockets are
8118 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558119 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008120
8121 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238122 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008123}
8124
maksim.sisov0adf8592016-07-15 06:25:568125// Grab a socket, use it, and put it back into the pool. Then, make
8126// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018127TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568128 HttpRequestInfo request;
8129 request.method = "GET";
8130 request.url = GURL("http://www.example.org/");
8131 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108132 request.traffic_annotation =
8133 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568134
8135 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8136
bnc691fda62016-08-12 00:43:168137 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568138
8139 MockRead data_reads[] = {
8140 // A part of the response body is received with the response headers.
8141 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8142 // The rest of the response body is received in two parts.
8143 MockRead("lo"), MockRead(" world"),
8144 MockRead("junk"), // Should not be read!!
8145 MockRead(SYNCHRONOUS, OK),
8146 };
8147
Ryan Sleevib8d7ea02018-05-07 20:01:018148 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
maksim.sisov0adf8592016-07-15 06:25:568149 session_deps_.socket_factory->AddSocketDataProvider(&data);
8150
8151 TestCompletionCallback callback;
8152
tfarina42834112016-09-22 13:38:208153 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568154 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8155
8156 EXPECT_THAT(callback.GetResult(rv), IsOk());
8157
bnc691fda62016-08-12 00:43:168158 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568159 ASSERT_TRUE(response);
8160 EXPECT_TRUE(response->headers);
8161 std::string status_line = response->headers->GetStatusLine();
8162 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8163
8164 // Make memory critical notification and ensure the transaction still has been
8165 // operating right.
8166 base::MemoryPressureListener::NotifyMemoryPressure(
8167 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8168 base::RunLoop().RunUntilIdle();
8169
8170 // Socket should not be flushed as long as it is not idle.
8171 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8172
8173 std::string response_data;
bnc691fda62016-08-12 00:43:168174 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568175 EXPECT_THAT(rv, IsOk());
8176 EXPECT_EQ("hello world", response_data);
8177
8178 // Empty the current queue. This is necessary because idle sockets are
8179 // added to the connection pool asynchronously with a PostTask.
8180 base::RunLoop().RunUntilIdle();
8181
8182 // We now check to make sure the socket was added back to the pool.
8183 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8184
8185 // Idle sockets should be flushed now.
8186 base::MemoryPressureListener::NotifyMemoryPressure(
8187 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8188 base::RunLoop().RunUntilIdle();
8189
8190 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8191}
8192
yucliu48f235d2018-01-11 00:59:558193// Disable idle socket closing on memory pressure.
8194// Grab a socket, use it, and put it back into the pool. Then, make
8195// low memory notification and ensure the socket pool is NOT flushed.
8196TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
8197 HttpRequestInfo request;
8198 request.method = "GET";
8199 request.url = GURL("http://www.example.org/");
8200 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108201 request.traffic_annotation =
8202 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:558203
8204 // Disable idle socket closing on memory pressure.
8205 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
8206 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8207
8208 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8209
8210 MockRead data_reads[] = {
8211 // A part of the response body is received with the response headers.
8212 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8213 // The rest of the response body is received in two parts.
8214 MockRead("lo"), MockRead(" world"),
8215 MockRead("junk"), // Should not be read!!
8216 MockRead(SYNCHRONOUS, OK),
8217 };
8218
Ryan Sleevib8d7ea02018-05-07 20:01:018219 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
yucliu48f235d2018-01-11 00:59:558220 session_deps_.socket_factory->AddSocketDataProvider(&data);
8221
8222 TestCompletionCallback callback;
8223
8224 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
8225 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8226
8227 EXPECT_THAT(callback.GetResult(rv), IsOk());
8228
8229 const HttpResponseInfo* response = trans.GetResponseInfo();
8230 ASSERT_TRUE(response);
8231 EXPECT_TRUE(response->headers);
8232 std::string status_line = response->headers->GetStatusLine();
8233 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8234
8235 // Make memory critical notification and ensure the transaction still has been
8236 // operating right.
8237 base::MemoryPressureListener::NotifyMemoryPressure(
8238 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8239 base::RunLoop().RunUntilIdle();
8240
8241 // Socket should not be flushed as long as it is not idle.
8242 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8243
8244 std::string response_data;
8245 rv = ReadTransaction(&trans, &response_data);
8246 EXPECT_THAT(rv, IsOk());
8247 EXPECT_EQ("hello world", response_data);
8248
8249 // Empty the current queue. This is necessary because idle sockets are
8250 // added to the connection pool asynchronously with a PostTask.
8251 base::RunLoop().RunUntilIdle();
8252
8253 // We now check to make sure the socket was added back to the pool.
8254 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8255
8256 // Idle sockets should NOT be flushed on moderate memory pressure.
8257 base::MemoryPressureListener::NotifyMemoryPressure(
8258 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
8259 base::RunLoop().RunUntilIdle();
8260
8261 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8262
8263 // Idle sockets should NOT be flushed on critical memory pressure.
8264 base::MemoryPressureListener::NotifyMemoryPressure(
8265 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8266 base::RunLoop().RunUntilIdle();
8267
8268 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8269}
8270
maksim.sisov0adf8592016-07-15 06:25:568271// Grab an SSL socket, use it, and put it back into the pool. Then, make
8272// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018273TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568274 HttpRequestInfo request;
8275 request.method = "GET";
8276 request.url = GURL("https://www.example.org/");
8277 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108278 request.traffic_annotation =
8279 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568280
8281 MockWrite data_writes[] = {
8282 MockWrite("GET / HTTP/1.1\r\n"
8283 "Host: www.example.org\r\n"
8284 "Connection: keep-alive\r\n\r\n"),
8285 };
8286
8287 MockRead data_reads[] = {
8288 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8289 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
8290
8291 SSLSocketDataProvider ssl(ASYNC, OK);
8292 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8293
Ryan Sleevib8d7ea02018-05-07 20:01:018294 StaticSocketDataProvider data(data_reads, data_writes);
maksim.sisov0adf8592016-07-15 06:25:568295 session_deps_.socket_factory->AddSocketDataProvider(&data);
8296
8297 TestCompletionCallback callback;
8298
8299 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168300 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568301
Matt Menke9d5e2c92019-02-05 01:42:238302 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
tfarina42834112016-09-22 13:38:208303 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568304
8305 EXPECT_THAT(callback.GetResult(rv), IsOk());
8306
bnc691fda62016-08-12 00:43:168307 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568308 ASSERT_TRUE(response);
8309 ASSERT_TRUE(response->headers);
8310 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8311
8312 // Make memory critical notification and ensure the transaction still has been
8313 // operating right.
8314 base::MemoryPressureListener::NotifyMemoryPressure(
8315 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8316 base::RunLoop().RunUntilIdle();
8317
Matt Menke9d5e2c92019-02-05 01:42:238318 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568319
8320 std::string response_data;
bnc691fda62016-08-12 00:43:168321 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568322 EXPECT_THAT(rv, IsOk());
8323 EXPECT_EQ("hello world", response_data);
8324
8325 // Empty the current queue. This is necessary because idle sockets are
8326 // added to the connection pool asynchronously with a PostTask.
8327 base::RunLoop().RunUntilIdle();
8328
8329 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238330 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568331
8332 // Make memory notification once again and ensure idle socket is closed.
8333 base::MemoryPressureListener::NotifyMemoryPressure(
8334 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8335 base::RunLoop().RunUntilIdle();
8336
Matt Menke9d5e2c92019-02-05 01:42:238337 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568338}
8339
[email protected]b4404c02009-04-10 16:38:528340// Make sure that we recycle a socket after a zero-length response.
8341// http://crbug.com/9880
bncd16676a2016-07-20 16:23:018342TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:428343 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:528344 request.method = "GET";
bncce36dca22015-04-21 22:11:238345 request.url = GURL(
8346 "http://www.example.org/csi?v=3&s=web&action=&"
8347 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
8348 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
8349 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e62018-02-07 07:41:108350 request.traffic_annotation =
8351 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:528352
danakj1fd259a02016-04-16 03:17:098353 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278354
[email protected]b4404c02009-04-10 16:38:528355 MockRead data_reads[] = {
8356 MockRead("HTTP/1.1 204 No Content\r\n"
8357 "Content-Length: 0\r\n"
8358 "Content-Type: text/html\r\n\r\n"),
8359 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:068360 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:528361 };
8362
Ryan Sleevib8d7ea02018-05-07 20:01:018363 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:078364 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:528365
mmenkecc2298e2015-12-07 18:20:188366 // Transaction must be created after the MockReads, so it's destroyed before
8367 // them.
bnc691fda62016-08-12 00:43:168368 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:188369
[email protected]49639fa2011-12-20 23:22:418370 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:528371
tfarina42834112016-09-22 13:38:208372 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018373 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:528374
8375 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018376 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528377
bnc691fda62016-08-12 00:43:168378 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528379 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:528380
wezca1070932016-05-26 20:30:528381 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:528382 std::string status_line = response->headers->GetStatusLine();
8383 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
8384
[email protected]90499482013-06-01 00:39:508385 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528386
8387 std::string response_data;
bnc691fda62016-08-12 00:43:168388 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018389 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528390 EXPECT_EQ("", response_data);
8391
8392 // Empty the current queue. This is necessary because idle sockets are
8393 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558394 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:528395
8396 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508397 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528398}
8399
bncd16676a2016-07-20 16:23:018400TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:098401 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:228402 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:198403 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:228404 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:278405
[email protected]1c773ea12009-04-28 19:58:428406 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:518407 // Transaction 1: a GET request that succeeds. The socket is recycled
8408 // after use.
8409 request[0].method = "GET";
8410 request[0].url = GURL("http://www.google.com/");
8411 request[0].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108412 request[0].traffic_annotation =
8413 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518414 // Transaction 2: a POST request. Reuses the socket kept alive from
8415 // transaction 1. The first attempts fails when writing the POST data.
8416 // This causes the transaction to retry with a new socket. The second
8417 // attempt succeeds.
8418 request[1].method = "POST";
8419 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:278420 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:518421 request[1].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108422 request[1].traffic_annotation =
8423 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518424
danakj1fd259a02016-04-16 03:17:098425 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:518426
8427 // The first socket is used for transaction 1 and the first attempt of
8428 // transaction 2.
8429
8430 // The response of transaction 1.
8431 MockRead data_reads1[] = {
8432 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
8433 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068434 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518435 };
8436 // The mock write results of transaction 1 and the first attempt of
8437 // transaction 2.
8438 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:068439 MockWrite(SYNCHRONOUS, 64), // GET
8440 MockWrite(SYNCHRONOUS, 93), // POST
8441 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:518442 };
Ryan Sleevib8d7ea02018-05-07 20:01:018443 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:518444
8445 // The second socket is used for the second attempt of transaction 2.
8446
8447 // The response of transaction 2.
8448 MockRead data_reads2[] = {
8449 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
8450 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:068451 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518452 };
8453 // The mock write results of the second attempt of transaction 2.
8454 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:068455 MockWrite(SYNCHRONOUS, 93), // POST
8456 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:518457 };
Ryan Sleevib8d7ea02018-05-07 20:01:018458 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:518459
[email protected]bb88e1d32013-05-03 23:11:078460 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8461 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:518462
thestig9d3bb0c2015-01-24 00:49:518463 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:518464 "hello world", "welcome"
8465 };
8466
8467 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:168468 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:518469
[email protected]49639fa2011-12-20 23:22:418470 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:518471
tfarina42834112016-09-22 13:38:208472 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018473 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:518474
8475 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018476 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518477
bnc691fda62016-08-12 00:43:168478 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528479 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:518480
wezca1070932016-05-26 20:30:528481 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:518482 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8483
8484 std::string response_data;
bnc691fda62016-08-12 00:43:168485 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018486 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518487 EXPECT_EQ(kExpectedResponseData[i], response_data);
8488 }
8489}
[email protected]f9ee6b52008-11-08 06:46:238490
8491// Test the request-challenge-retry sequence for basic auth when there is
8492// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:168493// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:018494TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:428495 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238496 request.method = "GET";
bncce36dca22015-04-21 22:11:238497 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:418498 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:108499 request.traffic_annotation =
8500 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:298501
danakj1fd259a02016-04-16 03:17:098502 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168503 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278504
[email protected]a97cca42009-08-14 01:00:298505 // The password contains an escaped character -- for this test to pass it
8506 // will need to be unescaped by HttpNetworkTransaction.
8507 EXPECT_EQ("b%40r", request.url.password());
8508
[email protected]f9ee6b52008-11-08 06:46:238509 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238510 MockWrite(
8511 "GET / HTTP/1.1\r\n"
8512 "Host: www.example.org\r\n"
8513 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238514 };
8515
8516 MockRead data_reads1[] = {
8517 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8518 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8519 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068520 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238521 };
8522
[email protected]2262e3a2012-05-22 16:08:168523 // After the challenge above, the transaction will be restarted using the
8524 // identity from the url (foo, b@r) to answer the challenge.
8525 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238526 MockWrite(
8527 "GET / HTTP/1.1\r\n"
8528 "Host: www.example.org\r\n"
8529 "Connection: keep-alive\r\n"
8530 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168531 };
8532
8533 MockRead data_reads2[] = {
8534 MockRead("HTTP/1.0 200 OK\r\n"),
8535 MockRead("Content-Length: 100\r\n\r\n"),
8536 MockRead(SYNCHRONOUS, OK),
8537 };
8538
Ryan Sleevib8d7ea02018-05-07 20:01:018539 StaticSocketDataProvider data1(data_reads1, data_writes1);
8540 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078541 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8542 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238543
[email protected]49639fa2011-12-20 23:22:418544 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208545 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018546 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238547 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018548 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168549 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168550
8551 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168552 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018553 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168554 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018555 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168556 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228557
bnc691fda62016-08-12 00:43:168558 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528559 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168560
8561 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:528562 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168563
8564 EXPECT_EQ(100, response->headers->GetContentLength());
8565
8566 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558567 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:168568}
8569
8570// Test the request-challenge-retry sequence for basic auth when there is an
8571// incorrect identity in the URL. The identity from the URL should be used only
8572// once.
bncd16676a2016-07-20 16:23:018573TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:168574 HttpRequestInfo request;
8575 request.method = "GET";
8576 // Note: the URL has a username:password in it. The password "baz" is
8577 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:238578 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:168579
8580 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:108581 request.traffic_annotation =
8582 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:168583
danakj1fd259a02016-04-16 03:17:098584 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168585 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:168586
8587 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238588 MockWrite(
8589 "GET / HTTP/1.1\r\n"
8590 "Host: www.example.org\r\n"
8591 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168592 };
8593
8594 MockRead data_reads1[] = {
8595 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8596 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8597 MockRead("Content-Length: 10\r\n\r\n"),
8598 MockRead(SYNCHRONOUS, ERR_FAILED),
8599 };
8600
8601 // After the challenge above, the transaction will be restarted using the
8602 // identity from the url (foo, baz) to answer the challenge.
8603 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238604 MockWrite(
8605 "GET / HTTP/1.1\r\n"
8606 "Host: www.example.org\r\n"
8607 "Connection: keep-alive\r\n"
8608 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168609 };
8610
8611 MockRead data_reads2[] = {
8612 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8613 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8614 MockRead("Content-Length: 10\r\n\r\n"),
8615 MockRead(SYNCHRONOUS, ERR_FAILED),
8616 };
8617
8618 // After the challenge above, the transaction will be restarted using the
8619 // identity supplied by the user (foo, bar) to answer the challenge.
8620 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238621 MockWrite(
8622 "GET / HTTP/1.1\r\n"
8623 "Host: www.example.org\r\n"
8624 "Connection: keep-alive\r\n"
8625 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168626 };
8627
8628 MockRead data_reads3[] = {
8629 MockRead("HTTP/1.0 200 OK\r\n"),
8630 MockRead("Content-Length: 100\r\n\r\n"),
8631 MockRead(SYNCHRONOUS, OK),
8632 };
8633
Ryan Sleevib8d7ea02018-05-07 20:01:018634 StaticSocketDataProvider data1(data_reads1, data_writes1);
8635 StaticSocketDataProvider data2(data_reads2, data_writes2);
8636 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:078637 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8638 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8639 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:168640
8641 TestCompletionCallback callback1;
8642
tfarina42834112016-09-22 13:38:208643 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018644 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168645
8646 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018647 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:168648
bnc691fda62016-08-12 00:43:168649 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168650 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168651 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018652 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168653 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018654 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168655 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168656
bnc691fda62016-08-12 00:43:168657 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528658 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168659 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8660
8661 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168662 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018663 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168664 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018665 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168666 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168667
bnc691fda62016-08-12 00:43:168668 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528669 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168670
8671 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528672 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:168673
8674 EXPECT_EQ(100, response->headers->GetContentLength());
8675
[email protected]ea9dc9a2009-09-05 00:43:328676 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558677 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:328678}
8679
[email protected]2217aa22013-10-11 03:03:548680
8681// Test the request-challenge-retry sequence for basic auth when there is a
8682// correct identity in the URL, but its use is being suppressed. The identity
8683// from the URL should never be used.
bncd16676a2016-07-20 16:23:018684TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:548685 HttpRequestInfo request;
8686 request.method = "GET";
bncce36dca22015-04-21 22:11:238687 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:548688 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e62018-02-07 07:41:108689 request.traffic_annotation =
8690 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:548691
danakj1fd259a02016-04-16 03:17:098692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168693 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:548694
8695 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238696 MockWrite(
8697 "GET / HTTP/1.1\r\n"
8698 "Host: www.example.org\r\n"
8699 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548700 };
8701
8702 MockRead data_reads1[] = {
8703 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8704 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8705 MockRead("Content-Length: 10\r\n\r\n"),
8706 MockRead(SYNCHRONOUS, ERR_FAILED),
8707 };
8708
8709 // After the challenge above, the transaction will be restarted using the
8710 // identity supplied by the user, not the one in the URL, to answer the
8711 // challenge.
8712 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238713 MockWrite(
8714 "GET / HTTP/1.1\r\n"
8715 "Host: www.example.org\r\n"
8716 "Connection: keep-alive\r\n"
8717 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548718 };
8719
8720 MockRead data_reads3[] = {
8721 MockRead("HTTP/1.0 200 OK\r\n"),
8722 MockRead("Content-Length: 100\r\n\r\n"),
8723 MockRead(SYNCHRONOUS, OK),
8724 };
8725
Ryan Sleevib8d7ea02018-05-07 20:01:018726 StaticSocketDataProvider data1(data_reads1, data_writes1);
8727 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]2217aa22013-10-11 03:03:548728 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8729 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8730
8731 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208732 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548734 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018735 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168736 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548737
bnc691fda62016-08-12 00:43:168738 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528739 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548740 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
8741
8742 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168743 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018744 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548745 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018746 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168747 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548748
bnc691fda62016-08-12 00:43:168749 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528750 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548751
8752 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:528753 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:548754 EXPECT_EQ(100, response->headers->GetContentLength());
8755
8756 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558757 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:548758}
8759
[email protected]f9ee6b52008-11-08 06:46:238760// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:018761TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:098762 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:238763
8764 // Transaction 1: authenticate (foo, bar) on MyRealm1
8765 {
[email protected]1c773ea12009-04-28 19:58:428766 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238767 request.method = "GET";
bncce36dca22015-04-21 22:11:238768 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:108769 request.traffic_annotation =
8770 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238771
bnc691fda62016-08-12 00:43:168772 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278773
[email protected]f9ee6b52008-11-08 06:46:238774 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238775 MockWrite(
8776 "GET /x/y/z HTTP/1.1\r\n"
8777 "Host: www.example.org\r\n"
8778 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238779 };
8780
8781 MockRead data_reads1[] = {
8782 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8783 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8784 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068785 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238786 };
8787
8788 // Resend with authorization (username=foo, password=bar)
8789 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238790 MockWrite(
8791 "GET /x/y/z HTTP/1.1\r\n"
8792 "Host: www.example.org\r\n"
8793 "Connection: keep-alive\r\n"
8794 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238795 };
8796
8797 // Sever accepts the authorization.
8798 MockRead data_reads2[] = {
8799 MockRead("HTTP/1.0 200 OK\r\n"),
8800 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068801 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238802 };
8803
Ryan Sleevib8d7ea02018-05-07 20:01:018804 StaticSocketDataProvider data1(data_reads1, data_writes1);
8805 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078806 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8807 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238808
[email protected]49639fa2011-12-20 23:22:418809 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238810
tfarina42834112016-09-22 13:38:208811 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018812 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238813
8814 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018815 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238816
bnc691fda62016-08-12 00:43:168817 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528818 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048819 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238820
[email protected]49639fa2011-12-20 23:22:418821 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238822
bnc691fda62016-08-12 00:43:168823 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8824 callback2.callback());
robpercival214763f2016-07-01 23:27:018825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238826
8827 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018828 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238829
bnc691fda62016-08-12 00:43:168830 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528831 ASSERT_TRUE(response);
8832 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238833 EXPECT_EQ(100, response->headers->GetContentLength());
8834 }
8835
8836 // ------------------------------------------------------------------------
8837
8838 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
8839 {
[email protected]1c773ea12009-04-28 19:58:428840 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238841 request.method = "GET";
8842 // Note that Transaction 1 was at /x/y/z, so this is in the same
8843 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:238844 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:108845 request.traffic_annotation =
8846 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238847
bnc691fda62016-08-12 00:43:168848 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278849
[email protected]f9ee6b52008-11-08 06:46:238850 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238851 MockWrite(
8852 "GET /x/y/a/b HTTP/1.1\r\n"
8853 "Host: www.example.org\r\n"
8854 "Connection: keep-alive\r\n"
8855 // Send preemptive authorization for MyRealm1
8856 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238857 };
8858
8859 // The server didn't like the preemptive authorization, and
8860 // challenges us for a different realm (MyRealm2).
8861 MockRead data_reads1[] = {
8862 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8863 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8864 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068865 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238866 };
8867
8868 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8869 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238870 MockWrite(
8871 "GET /x/y/a/b HTTP/1.1\r\n"
8872 "Host: www.example.org\r\n"
8873 "Connection: keep-alive\r\n"
8874 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238875 };
8876
8877 // Sever accepts the authorization.
8878 MockRead data_reads2[] = {
8879 MockRead("HTTP/1.0 200 OK\r\n"),
8880 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068881 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238882 };
8883
Ryan Sleevib8d7ea02018-05-07 20:01:018884 StaticSocketDataProvider data1(data_reads1, data_writes1);
8885 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078886 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8887 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238888
[email protected]49639fa2011-12-20 23:22:418889 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238890
tfarina42834112016-09-22 13:38:208891 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018892 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238893
8894 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018895 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238896
bnc691fda62016-08-12 00:43:168897 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528898 ASSERT_TRUE(response);
8899 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048900 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438901 EXPECT_EQ("http://www.example.org",
8902 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048903 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198904 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238905
[email protected]49639fa2011-12-20 23:22:418906 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238907
bnc691fda62016-08-12 00:43:168908 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8909 callback2.callback());
robpercival214763f2016-07-01 23:27:018910 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238911
8912 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018913 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238914
bnc691fda62016-08-12 00:43:168915 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528916 ASSERT_TRUE(response);
8917 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238918 EXPECT_EQ(100, response->headers->GetContentLength());
8919 }
8920
8921 // ------------------------------------------------------------------------
8922
8923 // Transaction 3: Resend a request in MyRealm's protection space --
8924 // succeed with preemptive authorization.
8925 {
[email protected]1c773ea12009-04-28 19:58:428926 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238927 request.method = "GET";
bncce36dca22015-04-21 22:11:238928 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e62018-02-07 07:41:108929 request.traffic_annotation =
8930 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238931
bnc691fda62016-08-12 00:43:168932 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278933
[email protected]f9ee6b52008-11-08 06:46:238934 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238935 MockWrite(
8936 "GET /x/y/z2 HTTP/1.1\r\n"
8937 "Host: www.example.org\r\n"
8938 "Connection: keep-alive\r\n"
8939 // The authorization for MyRealm1 gets sent preemptively
8940 // (since the url is in the same protection space)
8941 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238942 };
8943
8944 // Sever accepts the preemptive authorization
8945 MockRead data_reads1[] = {
8946 MockRead("HTTP/1.0 200 OK\r\n"),
8947 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068948 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238949 };
8950
Ryan Sleevib8d7ea02018-05-07 20:01:018951 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078952 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238953
[email protected]49639fa2011-12-20 23:22:418954 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238955
tfarina42834112016-09-22 13:38:208956 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018957 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238958
8959 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018960 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238961
bnc691fda62016-08-12 00:43:168962 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528963 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238964
wezca1070932016-05-26 20:30:528965 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238966 EXPECT_EQ(100, response->headers->GetContentLength());
8967 }
8968
8969 // ------------------------------------------------------------------------
8970
8971 // Transaction 4: request another URL in MyRealm (however the
8972 // url is not known to belong to the protection space, so no pre-auth).
8973 {
[email protected]1c773ea12009-04-28 19:58:428974 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238975 request.method = "GET";
bncce36dca22015-04-21 22:11:238976 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e62018-02-07 07:41:108977 request.traffic_annotation =
8978 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238979
bnc691fda62016-08-12 00:43:168980 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278981
[email protected]f9ee6b52008-11-08 06:46:238982 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238983 MockWrite(
8984 "GET /x/1 HTTP/1.1\r\n"
8985 "Host: www.example.org\r\n"
8986 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238987 };
8988
8989 MockRead data_reads1[] = {
8990 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8991 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8992 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068993 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238994 };
8995
8996 // Resend with authorization from MyRealm's cache.
8997 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238998 MockWrite(
8999 "GET /x/1 HTTP/1.1\r\n"
9000 "Host: www.example.org\r\n"
9001 "Connection: keep-alive\r\n"
9002 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239003 };
9004
9005 // Sever accepts the authorization.
9006 MockRead data_reads2[] = {
9007 MockRead("HTTP/1.0 200 OK\r\n"),
9008 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069009 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239010 };
9011
Ryan Sleevib8d7ea02018-05-07 20:01:019012 StaticSocketDataProvider data1(data_reads1, data_writes1);
9013 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079014 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9015 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:239016
[email protected]49639fa2011-12-20 23:22:419017 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239018
tfarina42834112016-09-22 13:38:209019 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019020 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239021
9022 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019023 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239024
bnc691fda62016-08-12 00:43:169025 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419026 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169027 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019028 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229029 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019030 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169031 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229032
bnc691fda62016-08-12 00:43:169033 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529034 ASSERT_TRUE(response);
9035 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239036 EXPECT_EQ(100, response->headers->GetContentLength());
9037 }
9038
9039 // ------------------------------------------------------------------------
9040
9041 // Transaction 5: request a URL in MyRealm, but the server rejects the
9042 // cached identity. Should invalidate and re-prompt.
9043 {
[email protected]1c773ea12009-04-28 19:58:429044 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:239045 request.method = "GET";
bncce36dca22015-04-21 22:11:239046 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e62018-02-07 07:41:109047 request.traffic_annotation =
9048 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:239049
bnc691fda62016-08-12 00:43:169050 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279051
[email protected]f9ee6b52008-11-08 06:46:239052 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239053 MockWrite(
9054 "GET /p/q/t HTTP/1.1\r\n"
9055 "Host: www.example.org\r\n"
9056 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239057 };
9058
9059 MockRead data_reads1[] = {
9060 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9061 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9062 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069063 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239064 };
9065
9066 // Resend with authorization from cache for MyRealm.
9067 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239068 MockWrite(
9069 "GET /p/q/t HTTP/1.1\r\n"
9070 "Host: www.example.org\r\n"
9071 "Connection: keep-alive\r\n"
9072 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239073 };
9074
9075 // Sever rejects the authorization.
9076 MockRead data_reads2[] = {
9077 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9078 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9079 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069080 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239081 };
9082
9083 // At this point we should prompt for new credentials for MyRealm.
9084 // Restart with username=foo3, password=foo4.
9085 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239086 MockWrite(
9087 "GET /p/q/t HTTP/1.1\r\n"
9088 "Host: www.example.org\r\n"
9089 "Connection: keep-alive\r\n"
9090 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239091 };
9092
9093 // Sever accepts the authorization.
9094 MockRead data_reads3[] = {
9095 MockRead("HTTP/1.0 200 OK\r\n"),
9096 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069097 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239098 };
9099
Ryan Sleevib8d7ea02018-05-07 20:01:019100 StaticSocketDataProvider data1(data_reads1, data_writes1);
9101 StaticSocketDataProvider data2(data_reads2, data_writes2);
9102 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:079103 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9104 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9105 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:239106
[email protected]49639fa2011-12-20 23:22:419107 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239108
tfarina42834112016-09-22 13:38:209109 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239111
9112 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019113 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239114
bnc691fda62016-08-12 00:43:169115 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419116 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169117 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229119 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019120 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169121 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229122
bnc691fda62016-08-12 00:43:169123 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529124 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049125 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:239126
[email protected]49639fa2011-12-20 23:22:419127 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:239128
bnc691fda62016-08-12 00:43:169129 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
9130 callback3.callback());
robpercival214763f2016-07-01 23:27:019131 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239132
[email protected]0757e7702009-03-27 04:00:229133 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:019134 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239135
bnc691fda62016-08-12 00:43:169136 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529137 ASSERT_TRUE(response);
9138 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:239139 EXPECT_EQ(100, response->headers->GetContentLength());
9140 }
9141}
[email protected]89ceba9a2009-03-21 03:46:069142
[email protected]3c32c5f2010-05-18 15:18:129143// Tests that nonce count increments when multiple auth attempts
9144// are started with the same nonce.
bncd16676a2016-07-20 16:23:019145TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:449146 HttpAuthHandlerDigest::Factory* digest_factory =
9147 new HttpAuthHandlerDigest::Factory();
9148 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
9149 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
9150 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:079151 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:099152 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:129153
9154 // Transaction 1: authenticate (foo, bar) on MyRealm1
9155 {
[email protected]3c32c5f2010-05-18 15:18:129156 HttpRequestInfo request;
9157 request.method = "GET";
bncce36dca22015-04-21 22:11:239158 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:109159 request.traffic_annotation =
9160 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129161
bnc691fda62016-08-12 00:43:169162 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279163
[email protected]3c32c5f2010-05-18 15:18:129164 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239165 MockWrite(
9166 "GET /x/y/z HTTP/1.1\r\n"
9167 "Host: www.example.org\r\n"
9168 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129169 };
9170
9171 MockRead data_reads1[] = {
9172 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9173 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
9174 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069175 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129176 };
9177
9178 // Resend with authorization (username=foo, password=bar)
9179 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239180 MockWrite(
9181 "GET /x/y/z HTTP/1.1\r\n"
9182 "Host: www.example.org\r\n"
9183 "Connection: keep-alive\r\n"
9184 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9185 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
9186 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
9187 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129188 };
9189
9190 // Sever accepts the authorization.
9191 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:089192 MockRead("HTTP/1.0 200 OK\r\n"),
9193 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129194 };
9195
Ryan Sleevib8d7ea02018-05-07 20:01:019196 StaticSocketDataProvider data1(data_reads1, data_writes1);
9197 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079198 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9199 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:129200
[email protected]49639fa2011-12-20 23:22:419201 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129202
tfarina42834112016-09-22 13:38:209203 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019204 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129205
9206 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019207 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129208
bnc691fda62016-08-12 00:43:169209 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529210 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049211 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:129212
[email protected]49639fa2011-12-20 23:22:419213 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:129214
bnc691fda62016-08-12 00:43:169215 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
9216 callback2.callback());
robpercival214763f2016-07-01 23:27:019217 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129218
9219 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019220 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129221
bnc691fda62016-08-12 00:43:169222 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529223 ASSERT_TRUE(response);
9224 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129225 }
9226
9227 // ------------------------------------------------------------------------
9228
9229 // Transaction 2: Request another resource in digestive's protection space.
9230 // This will preemptively add an Authorization header which should have an
9231 // "nc" value of 2 (as compared to 1 in the first use.
9232 {
[email protected]3c32c5f2010-05-18 15:18:129233 HttpRequestInfo request;
9234 request.method = "GET";
9235 // Note that Transaction 1 was at /x/y/z, so this is in the same
9236 // protection space as digest.
bncce36dca22015-04-21 22:11:239237 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:109238 request.traffic_annotation =
9239 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129240
bnc691fda62016-08-12 00:43:169241 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279242
[email protected]3c32c5f2010-05-18 15:18:129243 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239244 MockWrite(
9245 "GET /x/y/a/b HTTP/1.1\r\n"
9246 "Host: www.example.org\r\n"
9247 "Connection: keep-alive\r\n"
9248 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9249 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
9250 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
9251 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129252 };
9253
9254 // Sever accepts the authorization.
9255 MockRead data_reads1[] = {
9256 MockRead("HTTP/1.0 200 OK\r\n"),
9257 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069258 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129259 };
9260
Ryan Sleevib8d7ea02018-05-07 20:01:019261 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:079262 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:129263
[email protected]49639fa2011-12-20 23:22:419264 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129265
tfarina42834112016-09-22 13:38:209266 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019267 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129268
9269 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019270 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129271
bnc691fda62016-08-12 00:43:169272 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529273 ASSERT_TRUE(response);
9274 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:129275 }
9276}
9277
[email protected]89ceba9a2009-03-21 03:46:069278// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:019279TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:069280 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:099281 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169282 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:069283
9284 // Setup some state (which we expect ResetStateForRestart() will clear).
Victor Costan9c7302b2018-08-27 16:39:449285 trans.read_buf_ = base::MakeRefCounted<IOBuffer>(15);
bnc691fda62016-08-12 00:43:169286 trans.read_buf_len_ = 15;
9287 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:069288
9289 // Setup state in response_
bnc691fda62016-08-12 00:43:169290 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:579291 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:089292 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:579293 response->response_time = base::Time::Now();
9294 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:069295
9296 { // Setup state for response_.vary_data
9297 HttpRequestInfo request;
9298 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
9299 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:279300 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:439301 request.extra_headers.SetHeader("Foo", "1");
9302 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:509303 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:069304 }
9305
9306 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:169307 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:069308
9309 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:169310 EXPECT_FALSE(trans.read_buf_);
9311 EXPECT_EQ(0, trans.read_buf_len_);
9312 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:529313 EXPECT_FALSE(response->auth_challenge);
9314 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:049315 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:089316 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:579317 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:069318}
9319
[email protected]bacff652009-03-31 17:50:339320// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:019321TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:339322 HttpRequestInfo request;
9323 request.method = "GET";
bncce36dca22015-04-21 22:11:239324 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109325 request.traffic_annotation =
9326 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339327
danakj1fd259a02016-04-16 03:17:099328 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169329 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279330
[email protected]bacff652009-03-31 17:50:339331 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239332 MockWrite(
9333 "GET / HTTP/1.1\r\n"
9334 "Host: www.example.org\r\n"
9335 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339336 };
9337
9338 MockRead data_reads[] = {
9339 MockRead("HTTP/1.0 200 OK\r\n"),
9340 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9341 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069342 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339343 };
9344
[email protected]5ecc992a42009-11-11 01:41:599345 StaticSocketDataProvider ssl_bad_certificate;
Ryan Sleevib8d7ea02018-05-07 20:01:019346 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069347 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9348 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339349
[email protected]bb88e1d32013-05-03 23:11:079350 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9351 session_deps_.socket_factory->AddSocketDataProvider(&data);
9352 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9353 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339354
[email protected]49639fa2011-12-20 23:22:419355 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339356
tfarina42834112016-09-22 13:38:209357 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019358 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339359
9360 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019361 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339362
bnc691fda62016-08-12 00:43:169363 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019364 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339365
9366 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019367 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339368
bnc691fda62016-08-12 00:43:169369 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339370
wezca1070932016-05-26 20:30:529371 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339372 EXPECT_EQ(100, response->headers->GetContentLength());
9373}
9374
9375// Test HTTPS connections to a site with a bad certificate, going through a
9376// proxy
bncd16676a2016-07-20 16:23:019377TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499378 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9379 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339380
9381 HttpRequestInfo request;
9382 request.method = "GET";
bncce36dca22015-04-21 22:11:239383 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109384 request.traffic_annotation =
9385 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339386
9387 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:179388 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9389 "Host: www.example.org:443\r\n"
9390 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339391 };
9392
9393 MockRead proxy_reads[] = {
9394 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069395 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:339396 };
9397
9398 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179399 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9400 "Host: www.example.org:443\r\n"
9401 "Proxy-Connection: keep-alive\r\n\r\n"),
9402 MockWrite("GET / HTTP/1.1\r\n"
9403 "Host: www.example.org\r\n"
9404 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339405 };
9406
9407 MockRead data_reads[] = {
9408 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9409 MockRead("HTTP/1.0 200 OK\r\n"),
9410 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9411 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069412 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339413 };
9414
Ryan Sleevib8d7ea02018-05-07 20:01:019415 StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
9416 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069417 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9418 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339419
[email protected]bb88e1d32013-05-03 23:11:079420 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9421 session_deps_.socket_factory->AddSocketDataProvider(&data);
9422 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9423 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339424
[email protected]49639fa2011-12-20 23:22:419425 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339426
9427 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:079428 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:339429
danakj1fd259a02016-04-16 03:17:099430 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169431 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:339432
tfarina42834112016-09-22 13:38:209433 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019434 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339435
9436 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019437 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339438
bnc691fda62016-08-12 00:43:169439 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019440 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339441
9442 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019443 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339444
bnc691fda62016-08-12 00:43:169445 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339446
wezca1070932016-05-26 20:30:529447 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339448 EXPECT_EQ(100, response->headers->GetContentLength());
9449 }
9450}
9451
[email protected]2df19bb2010-08-25 20:13:469452
9453// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:019454TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599455 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499456 ProxyResolutionService::CreateFixedFromPacResult(
9457 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519458 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079459 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:469460
9461 HttpRequestInfo request;
9462 request.method = "GET";
bncce36dca22015-04-21 22:11:239463 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109464 request.traffic_annotation =
9465 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469466
9467 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179468 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9469 "Host: www.example.org:443\r\n"
9470 "Proxy-Connection: keep-alive\r\n\r\n"),
9471 MockWrite("GET / HTTP/1.1\r\n"
9472 "Host: www.example.org\r\n"
9473 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469474 };
9475
9476 MockRead data_reads[] = {
9477 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9478 MockRead("HTTP/1.1 200 OK\r\n"),
9479 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9480 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069481 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469482 };
9483
Ryan Sleevib8d7ea02018-05-07 20:01:019484 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069485 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9486 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:469487
[email protected]bb88e1d32013-05-03 23:11:079488 session_deps_.socket_factory->AddSocketDataProvider(&data);
9489 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9490 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:469491
[email protected]49639fa2011-12-20 23:22:419492 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469493
danakj1fd259a02016-04-16 03:17:099494 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169495 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469496
tfarina42834112016-09-22 13:38:209497 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019498 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469499
9500 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019501 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169502 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469503
wezca1070932016-05-26 20:30:529504 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469505
tbansal2ecbbc72016-10-06 17:15:479506 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:469507 EXPECT_TRUE(response->headers->IsKeepAlive());
9508 EXPECT_EQ(200, response->headers->response_code());
9509 EXPECT_EQ(100, response->headers->GetContentLength());
9510 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209511
9512 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169513 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209514 TestLoadTimingNotReusedWithPac(load_timing_info,
9515 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:469516}
9517
Eric Roman74103c72019-02-21 00:23:129518// Test that an HTTPS Proxy can redirect a CONNECT request for main frames.
bncd16676a2016-07-20 16:23:019519TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599520 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499521 ProxyResolutionService::CreateFixedFromPacResult(
9522 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519523 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079524 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:299525
Matt Menkeecfecfc72019-02-05 19:15:289526 base::TimeTicks start_time = base::TimeTicks::Now();
9527 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9528 session_deps_.host_resolver->set_ondemand_mode(true);
9529
[email protected]511f6f52010-12-17 03:58:299530 HttpRequestInfo request;
Eric Roman74103c72019-02-21 00:23:129531 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
[email protected]511f6f52010-12-17 03:58:299532 request.method = "GET";
bncce36dca22015-04-21 22:11:239533 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109534 request.traffic_annotation =
9535 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299536
9537 MockWrite data_writes[] = {
Matt Menkeecfecfc72019-02-05 19:15:289538 MockWrite(ASYNC, 0,
9539 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:179540 "Host: www.example.org:443\r\n"
9541 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299542 };
9543
9544 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289545 // Pause on first read.
9546 MockRead(ASYNC, ERR_IO_PENDING, 1),
9547 MockRead(ASYNC, 2, "HTTP/1.1 302 Redirect\r\n"),
9548 MockRead(ASYNC, 3, "Location: http://login.example.com/\r\n"),
9549 MockRead(ASYNC, 4, "Content-Length: 0\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299550 };
9551
Matt Menkeecfecfc72019-02-05 19:15:289552 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069553 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299554
[email protected]bb88e1d32013-05-03 23:11:079555 session_deps_.socket_factory->AddSocketDataProvider(&data);
9556 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299557
[email protected]49639fa2011-12-20 23:22:419558 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299559
danakj1fd259a02016-04-16 03:17:099560 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169561 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299562
tfarina42834112016-09-22 13:38:209563 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019564 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289565 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
9566
9567 // Host resolution takes |kTimeIncrement|.
9568 FastForwardBy(kTimeIncrement);
9569 // Resolving the current request with |ResolveNow| will cause the pending
9570 // request to instantly complete, and the async connect will start as well.
9571 session_deps_.host_resolver->ResolveOnlyRequestNow();
9572
9573 // Connecting takes |kTimeIncrement|.
9574 FastForwardBy(kTimeIncrement);
9575 data.RunUntilPaused();
9576
9577 // The server takes |kTimeIncrement| to respond.
9578 FastForwardBy(kTimeIncrement);
9579 data.Resume();
[email protected]511f6f52010-12-17 03:58:299580
9581 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019582 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169583 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299584
wezca1070932016-05-26 20:30:529585 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299586
9587 EXPECT_EQ(302, response->headers->response_code());
9588 std::string url;
9589 EXPECT_TRUE(response->headers->IsRedirect(&url));
9590 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:209591
[email protected]029c83b62013-01-24 05:28:209592 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169593 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209594
9595 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:199596 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:209597
Matt Menkeecfecfc72019-02-05 19:15:289598 // In the case of redirects from proxies, just as with all responses from
9599 // proxies, DNS and SSL times reflect timing to look up the destination's
9600 // name, and negotiate an SSL connection to it (Neither of which are done in
9601 // this case), which the DNS and SSL times for the proxy are all included in
9602 // connect_start / connect_end. See
Eric Roman74103c72019-02-21 00:23:129603 // HttpNetworkTransaction::OnHttpsProxyTunnelResponseRedirect
Matt Menkeecfecfc72019-02-05 19:15:289604
9605 EXPECT_TRUE(load_timing_info.connect_timing.dns_start.is_null());
9606 EXPECT_TRUE(load_timing_info.connect_timing.dns_end.is_null());
9607 EXPECT_TRUE(load_timing_info.connect_timing.ssl_start.is_null());
9608 EXPECT_TRUE(load_timing_info.connect_timing.ssl_end.is_null());
9609
9610 EXPECT_EQ(start_time, load_timing_info.proxy_resolve_start);
9611 EXPECT_EQ(start_time, load_timing_info.proxy_resolve_end);
9612 EXPECT_EQ(start_time, load_timing_info.connect_timing.connect_start);
9613 EXPECT_EQ(start_time + 3 * kTimeIncrement,
9614 load_timing_info.connect_timing.connect_end);
[email protected]029c83b62013-01-24 05:28:209615
9616 EXPECT_TRUE(load_timing_info.send_start.is_null());
9617 EXPECT_TRUE(load_timing_info.send_end.is_null());
9618 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:299619}
9620
Eric Roman74103c72019-02-21 00:23:129621// Test that an HTTPS Proxy cannot redirect a CONNECT request for subresources.
9622TEST_F(HttpNetworkTransactionTest,
9623 RedirectOfHttpsConnectSubresourceViaHttpsProxy) {
9624 base::HistogramTester histograms;
9625 session_deps_.proxy_resolution_service =
9626 ProxyResolutionService::CreateFixedFromPacResult(
9627 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9628 TestNetLog net_log;
9629 session_deps_.net_log = &net_log;
9630
9631 HttpRequestInfo request;
9632 request.method = "GET";
9633 request.url = GURL("https://www.example.org/");
9634 request.traffic_annotation =
9635 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9636
9637 MockWrite data_writes[] = {
9638 MockWrite(ASYNC, 0,
9639 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9640 "Host: www.example.org:443\r\n"
9641 "Proxy-Connection: keep-alive\r\n\r\n"),
9642 };
9643
9644 MockRead data_reads[] = {
9645 MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
9646 MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
9647 MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
9648 };
9649
9650 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
9651 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9652
9653 session_deps_.socket_factory->AddSocketDataProvider(&data);
9654 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9655
9656 TestCompletionCallback callback;
9657
9658 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9659 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9660
9661 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9662 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9663
9664 rv = callback.WaitForResult();
9665 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
9666
9667 histograms.ExpectUniqueSample(
9668 "Net.Proxy.RedirectDuringConnect",
9669 HttpNetworkTransaction::kSubresourceByExplicitProxy, 1);
9670}
9671
9672// Test that an HTTPS Proxy which was auto-detected cannot redirect a CONNECT
9673// request for main frames.
9674TEST_F(HttpNetworkTransactionTest,
9675 RedirectOfHttpsConnectViaAutoDetectedHttpsProxy) {
9676 base::HistogramTester histograms;
9677 session_deps_.proxy_resolution_service =
9678 ProxyResolutionService::CreateFixedFromAutoDetectedPacResult(
9679 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9680 TestNetLog net_log;
9681 session_deps_.net_log = &net_log;
9682
9683 HttpRequestInfo request;
9684 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
9685 request.method = "GET";
9686 request.url = GURL("https://www.example.org/");
9687 request.traffic_annotation =
9688 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9689
9690 MockWrite data_writes[] = {
9691 MockWrite(ASYNC, 0,
9692 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9693 "Host: www.example.org:443\r\n"
9694 "Proxy-Connection: keep-alive\r\n\r\n"),
9695 };
9696
9697 MockRead data_reads[] = {
9698 MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
9699 MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
9700 MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
9701 };
9702
9703 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
9704 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9705
9706 session_deps_.socket_factory->AddSocketDataProvider(&data);
9707 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9708
9709 TestCompletionCallback callback;
9710
9711 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9712 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9713
9714 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9715 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9716
9717 rv = callback.WaitForResult();
9718 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
9719
9720 histograms.ExpectUniqueSample(
9721 "Net.Proxy.RedirectDuringConnect",
9722 HttpNetworkTransaction::kMainFrameByAutoDetectedProxy, 1);
9723}
9724
9725// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request for main
9726// frames.
bncd16676a2016-07-20 16:23:019727TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Eric Roman74103c72019-02-21 00:23:129728 base::HistogramTester histograms;
Ramin Halavatica8d5252018-03-12 05:33:499729 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9730 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeecfecfc72019-02-05 19:15:289731 TestNetLog net_log;
9732 session_deps_.net_log = &net_log;
9733
9734 base::TimeTicks start_time = base::TimeTicks::Now();
9735 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9736 session_deps_.host_resolver->set_ondemand_mode(true);
[email protected]511f6f52010-12-17 03:58:299737
9738 HttpRequestInfo request;
9739 request.method = "GET";
Eric Roman74103c72019-02-21 00:23:129740 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
bncce36dca22015-04-21 22:11:239741 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109742 request.traffic_annotation =
9743 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299744
Ryan Hamilton0239aac2018-05-19 00:03:139745 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049746 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9747 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139748 spdy::SpdySerializedFrame goaway(
9749 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299750 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419751 CreateMockWrite(conn, 0, SYNCHRONOUS),
Matt Menkeecfecfc72019-02-05 19:15:289752 CreateMockWrite(goaway, 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:299753 };
9754
9755 static const char* const kExtraHeaders[] = {
9756 "location",
9757 "http://login.example.com/",
9758 };
Ryan Hamilton0239aac2018-05-19 00:03:139759 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249760 "302", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:299761 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289762 // Pause on first read.
9763 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2),
9764 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299765 };
9766
Matt Menkeecfecfc72019-02-05 19:15:289767 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069768 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369769 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299770
[email protected]bb88e1d32013-05-03 23:11:079771 session_deps_.socket_factory->AddSocketDataProvider(&data);
9772 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299773
[email protected]49639fa2011-12-20 23:22:419774 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299775
danakj1fd259a02016-04-16 03:17:099776 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299778
tfarina42834112016-09-22 13:38:209779 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289781 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
[email protected]511f6f52010-12-17 03:58:299782
Matt Menkeecfecfc72019-02-05 19:15:289783 // Host resolution takes |kTimeIncrement|.
9784 FastForwardBy(kTimeIncrement);
9785 // Resolving the current request with |ResolveNow| will cause the pending
9786 // request to instantly complete, and the async connect will start as well.
9787 session_deps_.host_resolver->ResolveOnlyRequestNow();
9788
9789 // Connecting takes |kTimeIncrement|.
9790 FastForwardBy(kTimeIncrement);
9791 data.RunUntilPaused();
9792
9793 FastForwardBy(kTimeIncrement);
9794 data.Resume();
[email protected]511f6f52010-12-17 03:58:299795 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019796 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169797 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:299798
wezca1070932016-05-26 20:30:529799 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:299800
9801 EXPECT_EQ(302, response->headers->response_code());
9802 std::string url;
9803 EXPECT_TRUE(response->headers->IsRedirect(&url));
9804 EXPECT_EQ("http://login.example.com/", url);
Matt Menkeecfecfc72019-02-05 19:15:289805
9806 LoadTimingInfo load_timing_info;
9807 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
9808
9809 EXPECT_FALSE(load_timing_info.socket_reused);
9810 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
9811
9812 // No proxy resolution times, since there's no PAC script.
9813 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
9814 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
9815
9816 // In the case of redirects from proxies, just as with all responses from
9817 // proxies, DNS and SSL times reflect timing to look up the destination's
9818 // name, and negotiate an SSL connection to it (Neither of which are done in
9819 // this case), which the DNS and SSL times for the proxy are all included in
9820 // connect_start / connect_end. See
Eric Roman74103c72019-02-21 00:23:129821 // HttpNetworkTransaction::OnHttpsProxyTunnelResponseRedirect.
Matt Menkeecfecfc72019-02-05 19:15:289822
9823 EXPECT_TRUE(load_timing_info.connect_timing.dns_start.is_null());
9824 EXPECT_TRUE(load_timing_info.connect_timing.dns_end.is_null());
9825 EXPECT_TRUE(load_timing_info.connect_timing.ssl_start.is_null());
9826 EXPECT_TRUE(load_timing_info.connect_timing.ssl_end.is_null());
9827
9828 EXPECT_EQ(start_time, load_timing_info.connect_timing.connect_start);
9829 EXPECT_EQ(start_time + 3 * kTimeIncrement,
9830 load_timing_info.connect_timing.connect_end);
9831
9832 EXPECT_TRUE(load_timing_info.send_start.is_null());
9833 EXPECT_TRUE(load_timing_info.send_end.is_null());
9834 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
Eric Roman74103c72019-02-21 00:23:129835
9836 histograms.ExpectUniqueSample(
9837 "Net.Proxy.RedirectDuringConnect",
9838 HttpNetworkTransaction::kMainFrameByExplicitProxy, 1);
[email protected]511f6f52010-12-17 03:58:299839}
9840
[email protected]4eddbc732012-08-09 05:40:179841// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019842TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499843 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9844 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299845
9846 HttpRequestInfo request;
9847 request.method = "GET";
bncce36dca22015-04-21 22:11:239848 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109849 request.traffic_annotation =
9850 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299851
9852 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179853 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9854 "Host: www.example.org:443\r\n"
9855 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299856 };
9857
9858 MockRead data_reads[] = {
9859 MockRead("HTTP/1.1 404 Not Found\r\n"),
9860 MockRead("Content-Length: 23\r\n\r\n"),
9861 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:069862 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:299863 };
9864
Ryan Sleevib8d7ea02018-05-07 20:01:019865 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069866 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299867
[email protected]bb88e1d32013-05-03 23:11:079868 session_deps_.socket_factory->AddSocketDataProvider(&data);
9869 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299870
[email protected]49639fa2011-12-20 23:22:419871 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299872
danakj1fd259a02016-04-16 03:17:099873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169874 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299875
tfarina42834112016-09-22 13:38:209876 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019877 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299878
9879 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019880 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299881
ttuttle960fcbf2016-04-19 13:26:329882 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299883}
9884
[email protected]4eddbc732012-08-09 05:40:179885// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019886TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499887 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9888 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299889
9890 HttpRequestInfo request;
9891 request.method = "GET";
bncce36dca22015-04-21 22:11:239892 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109893 request.traffic_annotation =
9894 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299895
Ryan Hamilton0239aac2018-05-19 00:03:139896 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049897 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9898 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139899 spdy::SpdySerializedFrame rst(
9900 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299901 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419902 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:299903 };
9904
9905 static const char* const kExtraHeaders[] = {
9906 "location",
9907 "http://login.example.com/",
9908 };
Ryan Hamilton0239aac2018-05-19 00:03:139909 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249910 "404", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:139911 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:199912 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:299913 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:419914 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:139915 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299916 };
9917
Ryan Sleevib8d7ea02018-05-07 20:01:019918 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069919 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369920 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299921
[email protected]bb88e1d32013-05-03 23:11:079922 session_deps_.socket_factory->AddSocketDataProvider(&data);
9923 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299924
[email protected]49639fa2011-12-20 23:22:419925 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299926
danakj1fd259a02016-04-16 03:17:099927 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169928 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299929
tfarina42834112016-09-22 13:38:209930 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019931 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299932
9933 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019934 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299935
ttuttle960fcbf2016-04-19 13:26:329936 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299937}
9938
[email protected]0c5fb722012-02-28 11:50:359939// Test the request-challenge-retry sequence for basic auth, through
9940// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:019941TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:359942 HttpRequestInfo request;
9943 request.method = "GET";
bncce36dca22015-04-21 22:11:239944 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:359945 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:299946 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:109947 request.traffic_annotation =
9948 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:359949
9950 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599951 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499952 ProxyResolutionService::CreateFixedFromPacResult(
9953 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519954 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079955 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:099956 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:359957
9958 // Since we have proxy, should try to establish tunnel.
Ryan Hamilton0239aac2018-05-19 00:03:139959 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049960 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9961 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139962 spdy::SpdySerializedFrame rst(
9963 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:389964 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:359965
bnc691fda62016-08-12 00:43:169966 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:359967 // be issuing -- the final header line contains the credentials.
9968 const char* const kAuthCredentials[] = {
9969 "proxy-authorization", "Basic Zm9vOmJhcg==",
9970 };
Ryan Hamilton0239aac2018-05-19 00:03:139971 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049972 kAuthCredentials, base::size(kAuthCredentials) / 2, 3,
9973 HttpProxyConnectJob::kH2QuicTunnelPriority,
bncce36dca22015-04-21 22:11:239974 HostPortPair("www.example.org", 443)));
9975 // fetch https://www.example.org/ via HTTP
9976 const char get[] =
9977 "GET / HTTP/1.1\r\n"
9978 "Host: www.example.org\r\n"
9979 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:139980 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:199981 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:359982
9983 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419984 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
9985 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:359986 };
9987
9988 // The proxy responds to the connect with a 407, using a persistent
9989 // connection.
thestig9d3bb0c2015-01-24 00:49:519990 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:359991 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:359992 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
9993 };
Ryan Hamilton0239aac2018-05-19 00:03:139994 spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249995 kAuthStatus, kAuthChallenge, base::size(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:359996
Ryan Hamilton0239aac2018-05-19 00:03:139997 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:359998 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
[email protected]0c5fb722012-02-28 11:50:359999 const char resp[] = "HTTP/1.1 200 OK\r\n"
10000 "Content-Length: 5\r\n\r\n";
10001
Ryan Hamilton0239aac2018-05-19 00:03:1310002 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:1910003 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:1310004 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:1910005 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:3510006 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110007 CreateMockRead(conn_auth_resp, 1, ASYNC),
10008 CreateMockRead(conn_resp, 4, ASYNC),
10009 CreateMockRead(wrapped_get_resp, 6, ASYNC),
10010 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:1310011 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:3510012 };
10013
Ryan Sleevib8d7ea02018-05-07 20:01:0110014 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710015 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:3510016 // Negotiate SPDY to the proxy
10017 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610018 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710019 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:3510020 // Vanilla SSL to the server
10021 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710022 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:3510023
10024 TestCompletionCallback callback1;
10025
bnc87dcefc2017-05-25 12:47:5810026 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910027 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:3510028
10029 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110030 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:3510031
10032 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110033 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4610034 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:3510035 log.GetEntries(&entries);
10036 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0010037 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
10038 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:3510039 ExpectLogContainsSomewhere(
10040 entries, pos,
mikecirone8b85c432016-09-08 19:11:0010041 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10042 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:3510043
10044 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210045 ASSERT_TRUE(response);
10046 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:3510047 EXPECT_EQ(407, response->headers->response_code());
10048 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:5210049 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:4310050 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:3510051
10052 TestCompletionCallback callback2;
10053
10054 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
10055 callback2.callback());
robpercival214763f2016-07-01 23:27:0110056 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:3510057
10058 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110059 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:3510060
10061 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210062 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:3510063
10064 EXPECT_TRUE(response->headers->IsKeepAlive());
10065 EXPECT_EQ(200, response->headers->response_code());
10066 EXPECT_EQ(5, response->headers->GetContentLength());
10067 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10068
10069 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:5210070 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:3510071
[email protected]029c83b62013-01-24 05:28:2010072 LoadTimingInfo load_timing_info;
10073 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10074 TestLoadTimingNotReusedWithPac(load_timing_info,
10075 CONNECT_TIMING_HAS_SSL_TIMES);
10076
[email protected]0c5fb722012-02-28 11:50:3510077 trans.reset();
10078 session->CloseAllConnections();
10079}
10080
[email protected]7c6f7ba2012-04-03 04:09:2910081// Test that an explicitly trusted SPDY proxy can push a resource from an
10082// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:0110083TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:1510084 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910085 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510086 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10087 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:2910088 HttpRequestInfo request;
10089 HttpRequestInfo push_request;
Ramin Halavatib5e433e62018-02-07 07:41:1010090 request.traffic_annotation =
10091 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:2910092
[email protected]7c6f7ba2012-04-03 04:09:2910093 request.method = "GET";
bncce36dca22015-04-21 22:11:2310094 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:2910095 push_request.method = "GET";
10096 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e62018-02-07 07:41:1010097 push_request.traffic_annotation =
10098 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:2910099
tbansal28e68f82016-02-04 02:56:1510100 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:5910101 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910102 ProxyResolutionService::CreateFixedFromPacResult(
10103 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110104 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710105 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010106
Eric Roman3d8546a2018-09-10 17:00:5210107 session_deps_.proxy_resolution_service->SetProxyDelegate(
10108 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010109
danakj1fd259a02016-04-16 03:17:0910110 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:2910111
Ryan Hamilton0239aac2018-05-19 00:03:1310112 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510113 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310114 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510115 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:2910116
10117 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110118 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510119 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:2910120 };
10121
Ryan Hamilton0239aac2018-05-19 00:03:1310122 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Raul Tambre94493c652019-03-11 17:18:3510123 nullptr, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
Bence Béky7bf94362018-01-10 13:19:3610124
Ryan Hamilton0239aac2018-05-19 00:03:1310125 spdy::SpdySerializedFrame stream1_reply(
Raul Tambre94493c652019-03-11 17:18:3510126 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:2910127
Ryan Hamilton0239aac2018-05-19 00:03:1310128 spdy::SpdySerializedFrame stream1_body(
10129 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:2910130
Ryan Hamilton0239aac2018-05-19 00:03:1310131 spdy::SpdySerializedFrame stream2_body(
Bence Békyd74f4382018-02-20 18:26:1910132 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:2910133
10134 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:3610135 CreateMockRead(stream2_syn, 1, ASYNC),
10136 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510137 CreateMockRead(stream1_body, 4, ASYNC),
10138 CreateMockRead(stream2_body, 5, ASYNC),
10139 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:2910140 };
10141
Ryan Sleevib8d7ea02018-05-07 20:01:0110142 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710143 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:2910144 // Negotiate SPDY to the proxy
10145 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610146 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710147 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:2910148
bnc87dcefc2017-05-25 12:47:5810149 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910150 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:2910151 TestCompletionCallback callback;
10152 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110153 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910154
10155 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110156 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910157 const HttpResponseInfo* response = trans->GetResponseInfo();
10158
bnc87dcefc2017-05-25 12:47:5810159 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:1910160 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:5010161 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110162 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910163
10164 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110165 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910166 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
10167
wezca1070932016-05-26 20:30:5210168 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:2910169 EXPECT_TRUE(response->headers->IsKeepAlive());
10170
10171 EXPECT_EQ(200, response->headers->response_code());
10172 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10173
10174 std::string response_data;
10175 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110176 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910177 EXPECT_EQ("hello!", response_data);
10178
[email protected]029c83b62013-01-24 05:28:2010179 LoadTimingInfo load_timing_info;
10180 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10181 TestLoadTimingNotReusedWithPac(load_timing_info,
10182 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10183
[email protected]7c6f7ba2012-04-03 04:09:2910184 // Verify the pushed stream.
wezca1070932016-05-26 20:30:5210185 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:2910186 EXPECT_EQ(200, push_response->headers->response_code());
10187
10188 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110189 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910190 EXPECT_EQ("pushed", response_data);
10191
[email protected]029c83b62013-01-24 05:28:2010192 LoadTimingInfo push_load_timing_info;
10193 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
10194 TestLoadTimingReusedWithPac(push_load_timing_info);
10195 // The transactions should share a socket ID, despite being for different
10196 // origins.
10197 EXPECT_EQ(load_timing_info.socket_log_id,
10198 push_load_timing_info.socket_log_id);
10199
[email protected]7c6f7ba2012-04-03 04:09:2910200 trans.reset();
10201 push_trans.reset();
10202 session->CloseAllConnections();
10203}
10204
[email protected]8c843192012-04-05 07:15:0010205// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:0110206TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510207 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910208 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510209 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10210 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:0010211 HttpRequestInfo request;
10212
10213 request.method = "GET";
bncce36dca22015-04-21 22:11:2310214 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010215 request.traffic_annotation =
10216 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:0010217
Ramin Halavatica8d5252018-03-12 05:33:4910218 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10219 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110220 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710221 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010222
10223 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210224 session_deps_.proxy_resolution_service->SetProxyDelegate(
10225 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010226
danakj1fd259a02016-04-16 03:17:0910227 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:0010228
Ryan Hamilton0239aac2018-05-19 00:03:1310229 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510230 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:0010231
Ryan Hamilton0239aac2018-05-19 00:03:1310232 spdy::SpdySerializedFrame push_rst(
10233 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:0010234
10235 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110236 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:0010237 };
10238
Ryan Hamilton0239aac2018-05-19 00:03:1310239 spdy::SpdySerializedFrame stream1_reply(
Raul Tambre94493c652019-03-11 17:18:3510240 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]8c843192012-04-05 07:15:0010241
Ryan Hamilton0239aac2018-05-19 00:03:1310242 spdy::SpdySerializedFrame stream1_body(
10243 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:0010244
Ryan Hamilton0239aac2018-05-19 00:03:1310245 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Raul Tambre94493c652019-03-11 17:18:3510246 nullptr, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:0010247
10248 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110249 CreateMockRead(stream1_reply, 1, ASYNC),
10250 CreateMockRead(stream2_syn, 2, ASYNC),
10251 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:5910252 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:0010253 };
10254
Ryan Sleevib8d7ea02018-05-07 20:01:0110255 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710256 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:0010257 // Negotiate SPDY to the proxy
10258 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610259 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710260 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:0010261
bnc87dcefc2017-05-25 12:47:5810262 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910263 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:0010264 TestCompletionCallback callback;
10265 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110266 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:0010267
10268 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110269 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010270 const HttpResponseInfo* response = trans->GetResponseInfo();
10271
wezca1070932016-05-26 20:30:5210272 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:0010273 EXPECT_TRUE(response->headers->IsKeepAlive());
10274
10275 EXPECT_EQ(200, response->headers->response_code());
10276 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10277
10278 std::string response_data;
10279 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110280 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010281 EXPECT_EQ("hello!", response_data);
10282
10283 trans.reset();
10284 session->CloseAllConnections();
10285}
10286
tbansal8ef1d3e2016-02-03 04:05:4210287// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
10288// resources.
bncd16676a2016-07-20 16:23:0110289TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510290 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910291 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510292 proxy_delegate->set_trusted_spdy_proxy(
10293 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
10294
tbansal8ef1d3e2016-02-03 04:05:4210295 HttpRequestInfo request;
10296
10297 request.method = "GET";
10298 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010299 request.traffic_annotation =
10300 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210301
10302 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:4910303 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10304 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210305 BoundTestNetLog log;
10306 session_deps_.net_log = log.bound().net_log();
10307
10308 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210309 session_deps_.proxy_resolution_service->SetProxyDelegate(
10310 proxy_delegate.get());
tbansal8ef1d3e2016-02-03 04:05:4210311
danakj1fd259a02016-04-16 03:17:0910312 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:4210313
Ryan Hamilton0239aac2018-05-19 00:03:1310314 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510315 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310316 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510317 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:4210318
10319 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110320 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510321 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:4210322 };
10323
Ryan Hamilton0239aac2018-05-19 00:03:1310324 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:1510325 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210326
Ryan Hamilton0239aac2018-05-19 00:03:1310327 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:3310328 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:4910329
Ryan Hamilton0239aac2018-05-19 00:03:1310330 spdy::SpdySerializedFrame stream1_body(
10331 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210332
Ryan Hamilton0239aac2018-05-19 00:03:1310333 spdy::SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:1510334 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210335
Ryan Hamilton0239aac2018-05-19 00:03:1310336 spdy::SpdySerializedFrame stream2_body(
10337 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210338
10339 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110340 CreateMockRead(stream1_reply, 1, ASYNC),
10341 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510342 CreateMockRead(stream1_body, 4, ASYNC),
10343 CreateMockRead(stream2_body, 5, ASYNC),
10344 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:4210345 };
10346
Ryan Sleevib8d7ea02018-05-07 20:01:0110347 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
tbansal8ef1d3e2016-02-03 04:05:4210348 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10349 // Negotiate SPDY to the proxy
10350 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610351 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:4210352 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
10353
bnc87dcefc2017-05-25 12:47:5810354 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910355 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:4210356 TestCompletionCallback callback;
10357 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110358 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:4210359
10360 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110361 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210362 const HttpResponseInfo* response = trans->GetResponseInfo();
10363
wezca1070932016-05-26 20:30:5210364 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:4210365 EXPECT_TRUE(response->headers->IsKeepAlive());
10366
10367 EXPECT_EQ(200, response->headers->response_code());
10368 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10369
10370 std::string response_data;
10371 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110372 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210373 EXPECT_EQ("hello!", response_data);
10374
10375 trans.reset();
10376 session->CloseAllConnections();
10377}
10378
[email protected]2df19bb2010-08-25 20:13:4610379// Test HTTPS connections to a site with a bad certificate, going through an
10380// HTTPS proxy
bncd16676a2016-07-20 16:23:0110381TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:4910382 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10383 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610384
10385 HttpRequestInfo request;
10386 request.method = "GET";
bncce36dca22015-04-21 22:11:2310387 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010388 request.traffic_annotation =
10389 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610390
10391 // Attempt to fetch the URL from a server with a bad cert
10392 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710393 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10394 "Host: www.example.org:443\r\n"
10395 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610396 };
10397
10398 MockRead bad_cert_reads[] = {
10399 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610400 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:4610401 };
10402
10403 // Attempt to fetch the URL with a good cert
10404 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710405 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10406 "Host: www.example.org:443\r\n"
10407 "Proxy-Connection: keep-alive\r\n\r\n"),
10408 MockWrite("GET / HTTP/1.1\r\n"
10409 "Host: www.example.org\r\n"
10410 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610411 };
10412
10413 MockRead good_cert_reads[] = {
10414 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
10415 MockRead("HTTP/1.0 200 OK\r\n"),
10416 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10417 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610418 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:4610419 };
10420
Ryan Sleevib8d7ea02018-05-07 20:01:0110421 StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
10422 StaticSocketDataProvider data(good_cert_reads, good_data_writes);
[email protected]8ddf8322012-02-23 18:08:0610423 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
10424 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:4610425
10426 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:0710427 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10428 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
10429 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:4610430
10431 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:0710432 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10433 session_deps_.socket_factory->AddSocketDataProvider(&data);
10434 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:4610435
[email protected]49639fa2011-12-20 23:22:4110436 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:4610437
danakj1fd259a02016-04-16 03:17:0910438 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610439 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:4610440
tfarina42834112016-09-22 13:38:2010441 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110442 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610443
10444 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110445 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:4610446
bnc691fda62016-08-12 00:43:1610447 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:0110448 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610449
10450 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110451 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:4610452
bnc691fda62016-08-12 00:43:1610453 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:4610454
wezca1070932016-05-26 20:30:5210455 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:4610456 EXPECT_EQ(100, response->headers->GetContentLength());
10457}
10458
bncd16676a2016-07-20 16:23:0110459TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:4210460 HttpRequestInfo request;
10461 request.method = "GET";
bncce36dca22015-04-21 22:11:2310462 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310463 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10464 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:1010465 request.traffic_annotation =
10466 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210467
danakj1fd259a02016-04-16 03:17:0910468 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610469 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710470
[email protected]1c773ea12009-04-28 19:58:4210471 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310472 MockWrite(
10473 "GET / HTTP/1.1\r\n"
10474 "Host: www.example.org\r\n"
10475 "Connection: keep-alive\r\n"
10476 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210477 };
10478
10479 // Lastly, the server responds with the actual content.
10480 MockRead data_reads[] = {
10481 MockRead("HTTP/1.0 200 OK\r\n"),
10482 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10483 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610484 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210485 };
10486
Ryan Sleevib8d7ea02018-05-07 20:01:0110487 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710488 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210489
[email protected]49639fa2011-12-20 23:22:4110490 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210491
tfarina42834112016-09-22 13:38:2010492 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110493 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210494
10495 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110496 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210497}
10498
bncd16676a2016-07-20 16:23:0110499TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
Matt Menked732ea42019-03-08 12:05:0010500 // Test user agent values, used both for the request header of the original
10501 // request, and the value returned by the HttpUserAgentSettings. nullptr means
10502 // no request header / no HttpUserAgentSettings object.
10503 const char* kTestUserAgents[] = {nullptr, "", "Foopy"};
[email protected]da81f132010-08-18 23:39:2910504
Matt Menked732ea42019-03-08 12:05:0010505 for (const char* setting_user_agent : kTestUserAgents) {
10506 if (!setting_user_agent) {
10507 session_deps_.http_user_agent_settings.reset();
10508 } else {
10509 session_deps_.http_user_agent_settings =
10510 std::make_unique<StaticHttpUserAgentSettings>(
10511 std::string() /* accept-language */, setting_user_agent);
10512 }
10513 session_deps_.proxy_resolution_service =
10514 ProxyResolutionService::CreateFixed("myproxy:70",
10515 TRAFFIC_ANNOTATION_FOR_TESTS);
10516 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10517 for (const char* request_user_agent : kTestUserAgents) {
10518 HttpRequestInfo request;
10519 request.method = "GET";
10520 request.url = GURL("https://www.example.org/");
10521 if (request_user_agent) {
10522 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10523 request_user_agent);
10524 }
10525 request.traffic_annotation =
10526 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710527
Matt Menked732ea42019-03-08 12:05:0010528 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]da81f132010-08-18 23:39:2910529
Matt Menked732ea42019-03-08 12:05:0010530 std::string expected_request;
10531 if (!setting_user_agent || strlen(setting_user_agent) == 0) {
10532 expected_request =
10533 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10534 "Host: www.example.org:443\r\n"
10535 "Proxy-Connection: keep-alive\r\n\r\n";
10536 } else {
10537 expected_request = base::StringPrintf(
10538 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10539 "Host: www.example.org:443\r\n"
10540 "Proxy-Connection: keep-alive\r\n"
10541 "User-Agent: %s\r\n\r\n",
10542 setting_user_agent);
10543 }
10544 MockWrite data_writes[] = {
10545 MockWrite(expected_request.c_str()),
10546 };
10547 MockRead data_reads[] = {
10548 // Return an error, so the transaction stops here (this test isn't
10549 // interested in the rest).
10550 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
10551 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10552 MockRead("Proxy-Connection: close\r\n\r\n"),
10553 };
[email protected]da81f132010-08-18 23:39:2910554
Matt Menked732ea42019-03-08 12:05:0010555 StaticSocketDataProvider data(data_reads, data_writes);
10556 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:2910557
Matt Menked732ea42019-03-08 12:05:0010558 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:2910559
Matt Menked732ea42019-03-08 12:05:0010560 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10561 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10562
10563 rv = callback.WaitForResult();
10564 EXPECT_THAT(rv, IsOk());
10565 }
10566 }
[email protected]da81f132010-08-18 23:39:2910567}
10568
bncd16676a2016-07-20 16:23:0110569TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:4210570 HttpRequestInfo request;
10571 request.method = "GET";
bncce36dca22015-04-21 22:11:2310572 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:1610573 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
10574 "http://the.previous.site.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010575 request.traffic_annotation =
10576 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210577
danakj1fd259a02016-04-16 03:17:0910578 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610579 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710580
[email protected]1c773ea12009-04-28 19:58:4210581 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310582 MockWrite(
10583 "GET / HTTP/1.1\r\n"
10584 "Host: www.example.org\r\n"
10585 "Connection: keep-alive\r\n"
10586 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210587 };
10588
10589 // Lastly, the server responds with the actual content.
10590 MockRead data_reads[] = {
10591 MockRead("HTTP/1.0 200 OK\r\n"),
10592 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10593 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610594 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210595 };
10596
Ryan Sleevib8d7ea02018-05-07 20:01:0110597 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710598 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210599
[email protected]49639fa2011-12-20 23:22:4110600 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210601
tfarina42834112016-09-22 13:38:2010602 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110603 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210604
10605 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110606 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210607}
10608
bncd16676a2016-07-20 16:23:0110609TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210610 HttpRequestInfo request;
10611 request.method = "POST";
bncce36dca22015-04-21 22:11:2310612 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010613 request.traffic_annotation =
10614 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210615
danakj1fd259a02016-04-16 03:17:0910616 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610617 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710618
[email protected]1c773ea12009-04-28 19:58:4210619 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310620 MockWrite(
10621 "POST / HTTP/1.1\r\n"
10622 "Host: www.example.org\r\n"
10623 "Connection: keep-alive\r\n"
10624 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210625 };
10626
10627 // Lastly, the server responds with the actual content.
10628 MockRead data_reads[] = {
10629 MockRead("HTTP/1.0 200 OK\r\n"),
10630 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10631 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610632 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210633 };
10634
Ryan Sleevib8d7ea02018-05-07 20:01:0110635 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710636 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210637
[email protected]49639fa2011-12-20 23:22:4110638 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210639
tfarina42834112016-09-22 13:38:2010640 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110641 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210642
10643 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110644 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210645}
10646
bncd16676a2016-07-20 16:23:0110647TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210648 HttpRequestInfo request;
10649 request.method = "PUT";
bncce36dca22015-04-21 22:11:2310650 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010651 request.traffic_annotation =
10652 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210653
danakj1fd259a02016-04-16 03:17:0910654 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610655 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710656
[email protected]1c773ea12009-04-28 19:58:4210657 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310658 MockWrite(
10659 "PUT / HTTP/1.1\r\n"
10660 "Host: www.example.org\r\n"
10661 "Connection: keep-alive\r\n"
10662 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210663 };
10664
10665 // Lastly, the server responds with the actual content.
10666 MockRead data_reads[] = {
10667 MockRead("HTTP/1.0 200 OK\r\n"),
10668 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10669 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610670 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210671 };
10672
Ryan Sleevib8d7ea02018-05-07 20:01:0110673 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710674 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210675
[email protected]49639fa2011-12-20 23:22:4110676 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210677
tfarina42834112016-09-22 13:38:2010678 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110679 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210680
10681 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110682 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210683}
10684
bncd16676a2016-07-20 16:23:0110685TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210686 HttpRequestInfo request;
10687 request.method = "HEAD";
bncce36dca22015-04-21 22:11:2310688 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010689 request.traffic_annotation =
10690 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210691
danakj1fd259a02016-04-16 03:17:0910692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610693 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710694
[email protected]1c773ea12009-04-28 19:58:4210695 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:1310696 MockWrite("HEAD / HTTP/1.1\r\n"
10697 "Host: www.example.org\r\n"
10698 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210699 };
10700
10701 // Lastly, the server responds with the actual content.
10702 MockRead data_reads[] = {
10703 MockRead("HTTP/1.0 200 OK\r\n"),
10704 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10705 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610706 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210707 };
10708
Ryan Sleevib8d7ea02018-05-07 20:01:0110709 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710710 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210711
[email protected]49639fa2011-12-20 23:22:4110712 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210713
tfarina42834112016-09-22 13:38:2010714 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110715 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210716
10717 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110718 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210719}
10720
bncd16676a2016-07-20 16:23:0110721TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:4210722 HttpRequestInfo request;
10723 request.method = "GET";
bncce36dca22015-04-21 22:11:2310724 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210725 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:1010726 request.traffic_annotation =
10727 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210728
danakj1fd259a02016-04-16 03:17:0910729 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710731
[email protected]1c773ea12009-04-28 19:58:4210732 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310733 MockWrite(
10734 "GET / HTTP/1.1\r\n"
10735 "Host: www.example.org\r\n"
10736 "Connection: keep-alive\r\n"
10737 "Pragma: no-cache\r\n"
10738 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210739 };
10740
10741 // Lastly, the server responds with the actual content.
10742 MockRead data_reads[] = {
10743 MockRead("HTTP/1.0 200 OK\r\n"),
10744 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10745 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610746 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210747 };
10748
Ryan Sleevib8d7ea02018-05-07 20:01:0110749 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710750 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210751
[email protected]49639fa2011-12-20 23:22:4110752 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210753
tfarina42834112016-09-22 13:38:2010754 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110755 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210756
10757 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110758 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210759}
10760
bncd16676a2016-07-20 16:23:0110761TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:4210762 HttpRequestInfo request;
10763 request.method = "GET";
bncce36dca22015-04-21 22:11:2310764 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210765 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:1010766 request.traffic_annotation =
10767 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210768
danakj1fd259a02016-04-16 03:17:0910769 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610770 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710771
[email protected]1c773ea12009-04-28 19:58:4210772 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310773 MockWrite(
10774 "GET / HTTP/1.1\r\n"
10775 "Host: www.example.org\r\n"
10776 "Connection: keep-alive\r\n"
10777 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210778 };
10779
10780 // Lastly, the server responds with the actual content.
10781 MockRead data_reads[] = {
10782 MockRead("HTTP/1.0 200 OK\r\n"),
10783 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10784 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610785 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210786 };
10787
Ryan Sleevib8d7ea02018-05-07 20:01:0110788 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710789 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210790
[email protected]49639fa2011-12-20 23:22:4110791 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210792
tfarina42834112016-09-22 13:38:2010793 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110794 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210795
10796 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110797 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210798}
10799
bncd16676a2016-07-20 16:23:0110800TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:4210801 HttpRequestInfo request;
10802 request.method = "GET";
bncce36dca22015-04-21 22:11:2310803 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310804 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e62018-02-07 07:41:1010805 request.traffic_annotation =
10806 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210807
danakj1fd259a02016-04-16 03:17:0910808 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610809 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710810
[email protected]1c773ea12009-04-28 19:58:4210811 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310812 MockWrite(
10813 "GET / HTTP/1.1\r\n"
10814 "Host: www.example.org\r\n"
10815 "Connection: keep-alive\r\n"
10816 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210817 };
10818
10819 // Lastly, the server responds with the actual content.
10820 MockRead data_reads[] = {
10821 MockRead("HTTP/1.0 200 OK\r\n"),
10822 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10823 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610824 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210825 };
10826
Ryan Sleevib8d7ea02018-05-07 20:01:0110827 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710828 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210829
[email protected]49639fa2011-12-20 23:22:4110830 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210831
tfarina42834112016-09-22 13:38:2010832 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110833 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210834
10835 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110836 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210837}
10838
bncd16676a2016-07-20 16:23:0110839TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:4710840 HttpRequestInfo request;
10841 request.method = "GET";
bncce36dca22015-04-21 22:11:2310842 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310843 request.extra_headers.SetHeader("referer", "www.foo.com");
10844 request.extra_headers.SetHeader("hEllo", "Kitty");
10845 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:1010846 request.traffic_annotation =
10847 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:4710848
danakj1fd259a02016-04-16 03:17:0910849 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610850 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710851
[email protected]270c6412010-03-29 22:02:4710852 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310853 MockWrite(
10854 "GET / HTTP/1.1\r\n"
10855 "Host: www.example.org\r\n"
10856 "Connection: keep-alive\r\n"
10857 "referer: www.foo.com\r\n"
10858 "hEllo: Kitty\r\n"
10859 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:4710860 };
10861
10862 // Lastly, the server responds with the actual content.
10863 MockRead data_reads[] = {
10864 MockRead("HTTP/1.0 200 OK\r\n"),
10865 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10866 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610867 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:4710868 };
10869
Ryan Sleevib8d7ea02018-05-07 20:01:0110870 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710871 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:4710872
[email protected]49639fa2011-12-20 23:22:4110873 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:4710874
tfarina42834112016-09-22 13:38:2010875 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110876 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:4710877
10878 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110879 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:4710880}
10881
bncd16676a2016-07-20 16:23:0110882TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710883 HttpRequestInfo request;
10884 request.method = "GET";
bncce36dca22015-04-21 22:11:2310885 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010886 request.traffic_annotation =
10887 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710888
Lily Houghton8c2f97d2018-01-22 05:06:5910889 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910890 ProxyResolutionService::CreateFixedFromPacResult(
10891 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110892 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710893 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210894
danakj1fd259a02016-04-16 03:17:0910895 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610896 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210897
[email protected]3cd17242009-06-23 02:59:0210898 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10899 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10900
10901 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410902 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10903 MockWrite("GET / HTTP/1.1\r\n"
10904 "Host: www.example.org\r\n"
10905 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210906
10907 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410908 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10909 MockRead("HTTP/1.0 200 OK\r\n"),
10910 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10911 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0210912
Ryan Sleevib8d7ea02018-05-07 20:01:0110913 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710914 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210915
[email protected]49639fa2011-12-20 23:22:4110916 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210917
tfarina42834112016-09-22 13:38:2010918 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110919 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210920
10921 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110922 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210923
bnc691fda62016-08-12 00:43:1610924 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210925 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:0210926
tbansal2ecbbc72016-10-06 17:15:4710927 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:2010928 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610929 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010930 TestLoadTimingNotReusedWithPac(load_timing_info,
10931 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10932
[email protected]3cd17242009-06-23 02:59:0210933 std::string response_text;
bnc691fda62016-08-12 00:43:1610934 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110935 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210936 EXPECT_EQ("Payload", response_text);
10937}
10938
bncd16676a2016-07-20 16:23:0110939TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710940 HttpRequestInfo request;
10941 request.method = "GET";
bncce36dca22015-04-21 22:11:2310942 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010943 request.traffic_annotation =
10944 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710945
Lily Houghton8c2f97d2018-01-22 05:06:5910946 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910947 ProxyResolutionService::CreateFixedFromPacResult(
10948 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110949 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710950 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210951
danakj1fd259a02016-04-16 03:17:0910952 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610953 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210954
[email protected]3cd17242009-06-23 02:59:0210955 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
10956 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10957
10958 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310959 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
Avi Drissman4365a4782018-12-28 19:26:2410960 base::size(write_buffer)),
10961 MockWrite("GET / HTTP/1.1\r\n"
10962 "Host: www.example.org\r\n"
10963 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210964
10965 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410966 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
10967 base::size(read_buffer)),
10968 MockRead("HTTP/1.0 200 OK\r\n"),
10969 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10970 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3510971
Ryan Sleevib8d7ea02018-05-07 20:01:0110972 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710973 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510974
[email protected]8ddf8322012-02-23 18:08:0610975 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710976 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:3510977
[email protected]49639fa2011-12-20 23:22:4110978 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510979
tfarina42834112016-09-22 13:38:2010980 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110981 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510982
10983 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110984 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510985
[email protected]029c83b62013-01-24 05:28:2010986 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610987 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010988 TestLoadTimingNotReusedWithPac(load_timing_info,
10989 CONNECT_TIMING_HAS_SSL_TIMES);
10990
bnc691fda62016-08-12 00:43:1610991 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210992 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710993 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510994
10995 std::string response_text;
bnc691fda62016-08-12 00:43:1610996 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110997 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510998 EXPECT_EQ("Payload", response_text);
10999}
11000
bncd16676a2016-07-20 16:23:0111001TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:2011002 HttpRequestInfo request;
11003 request.method = "GET";
bncce36dca22015-04-21 22:11:2311004 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011005 request.traffic_annotation =
11006 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:2011007
Ramin Halavatica8d5252018-03-12 05:33:4911008 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11009 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111010 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711011 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:2011012
danakj1fd259a02016-04-16 03:17:0911013 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611014 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:2011015
11016 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
11017 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
11018
11019 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411020 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
11021 MockWrite("GET / HTTP/1.1\r\n"
11022 "Host: www.example.org\r\n"
11023 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:2011024
11025 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411026 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
11027 MockRead("HTTP/1.0 200 OK\r\n"),
11028 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11029 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]029c83b62013-01-24 05:28:2011030
Ryan Sleevib8d7ea02018-05-07 20:01:0111031 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711032 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:2011033
11034 TestCompletionCallback callback;
11035
tfarina42834112016-09-22 13:38:2011036 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111037 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:2011038
11039 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111040 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2011041
bnc691fda62016-08-12 00:43:1611042 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211043 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:2011044
11045 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611046 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011047 TestLoadTimingNotReused(load_timing_info,
11048 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
11049
11050 std::string response_text;
bnc691fda62016-08-12 00:43:1611051 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111052 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2011053 EXPECT_EQ("Payload", response_text);
11054}
11055
bncd16676a2016-07-20 16:23:0111056TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2711057 HttpRequestInfo request;
11058 request.method = "GET";
bncce36dca22015-04-21 22:11:2311059 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011060 request.traffic_annotation =
11061 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711062
Lily Houghton8c2f97d2018-01-22 05:06:5911063 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911064 ProxyResolutionService::CreateFixedFromPacResult(
11065 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111066 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711067 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3511068
danakj1fd259a02016-04-16 03:17:0911069 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611070 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3511071
[email protected]e0c27be2009-07-15 13:09:3511072 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
11073 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3711074 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2311075 0x05, // Version
11076 0x01, // Command (CONNECT)
11077 0x00, // Reserved.
11078 0x03, // Address type (DOMAINNAME).
11079 0x0F, // Length of domain (15)
11080 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
11081 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3711082 };
[email protected]e0c27be2009-07-15 13:09:3511083 const char kSOCKS5OkResponse[] =
11084 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
11085
11086 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411087 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
11088 MockWrite(ASYNC, kSOCKS5OkRequest, base::size(kSOCKS5OkRequest)),
11089 MockWrite("GET / HTTP/1.1\r\n"
11090 "Host: www.example.org\r\n"
11091 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3511092
11093 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411094 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11095 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11096 MockRead("HTTP/1.0 200 OK\r\n"),
11097 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11098 MockRead("Payload"),
11099 MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3511100
Ryan Sleevib8d7ea02018-05-07 20:01:0111101 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711102 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3511103
[email protected]49639fa2011-12-20 23:22:4111104 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3511105
tfarina42834112016-09-22 13:38:2011106 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111107 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3511108
11109 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111110 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3511111
bnc691fda62016-08-12 00:43:1611112 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211113 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711114 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3511115
[email protected]029c83b62013-01-24 05:28:2011116 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611117 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011118 TestLoadTimingNotReusedWithPac(load_timing_info,
11119 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
11120
[email protected]e0c27be2009-07-15 13:09:3511121 std::string response_text;
bnc691fda62016-08-12 00:43:1611122 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111123 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3511124 EXPECT_EQ("Payload", response_text);
11125}
11126
bncd16676a2016-07-20 16:23:0111127TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2711128 HttpRequestInfo request;
11129 request.method = "GET";
bncce36dca22015-04-21 22:11:2311130 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011131 request.traffic_annotation =
11132 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711133
Lily Houghton8c2f97d2018-01-22 05:06:5911134 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911135 ProxyResolutionService::CreateFixedFromPacResult(
11136 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111137 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711138 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3511139
danakj1fd259a02016-04-16 03:17:0911140 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611141 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3511142
[email protected]e0c27be2009-07-15 13:09:3511143 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
11144 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3711145 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2311146 0x05, // Version
11147 0x01, // Command (CONNECT)
11148 0x00, // Reserved.
11149 0x03, // Address type (DOMAINNAME).
11150 0x0F, // Length of domain (15)
11151 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
11152 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3711153 };
11154
[email protected]e0c27be2009-07-15 13:09:3511155 const char kSOCKS5OkResponse[] =
11156 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
11157
11158 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411159 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
bncce36dca22015-04-21 22:11:2311160 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
Avi Drissman4365a4782018-12-28 19:26:2411161 base::size(kSOCKS5OkRequest)),
11162 MockWrite("GET / HTTP/1.1\r\n"
11163 "Host: www.example.org\r\n"
11164 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3511165
11166 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411167 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11168 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11169 MockRead("HTTP/1.0 200 OK\r\n"),
11170 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11171 MockRead("Payload"),
11172 MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0211173
Ryan Sleevib8d7ea02018-05-07 20:01:0111174 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711175 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0211176
[email protected]8ddf8322012-02-23 18:08:0611177 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711178 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0211179
[email protected]49639fa2011-12-20 23:22:4111180 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0211181
tfarina42834112016-09-22 13:38:2011182 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111183 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0211184
11185 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111186 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211187
bnc691fda62016-08-12 00:43:1611188 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211189 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711190 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0211191
[email protected]029c83b62013-01-24 05:28:2011192 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611193 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011194 TestLoadTimingNotReusedWithPac(load_timing_info,
11195 CONNECT_TIMING_HAS_SSL_TIMES);
11196
[email protected]3cd17242009-06-23 02:59:0211197 std::string response_text;
bnc691fda62016-08-12 00:43:1611198 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111199 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211200 EXPECT_EQ("Payload", response_text);
11201}
11202
[email protected]448d4ca52012-03-04 04:12:2311203namespace {
11204
Matt Menkef6edce752019-03-19 17:21:5611205// Tests that for connection endpoints the group ids are correctly set.
[email protected]2d731a32010-04-29 01:04:0611206
Matt Menkef6edce752019-03-19 17:21:5611207struct GroupIdTest {
[email protected]2d731a32010-04-29 01:04:0611208 std::string proxy_server;
11209 std::string url;
Matt Menkef6edce752019-03-19 17:21:5611210 ClientSocketPool::GroupId expected_group_id;
[email protected]e60e47a2010-07-14 03:37:1811211 bool ssl;
[email protected]2d731a32010-04-29 01:04:0611212};
11213
Matt Menkef6edce752019-03-19 17:21:5611214std::unique_ptr<HttpNetworkSession> SetupSessionForGroupIdTests(
[email protected]bb88e1d32013-05-03 23:11:0711215 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0911216 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0611217
bnc525e175a2016-06-20 12:36:4011218 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311219 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111220 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1211221 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111222 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4211223 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4611224 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0611225
11226 return session;
11227}
11228
Matt Menkef6edce752019-03-19 17:21:5611229int GroupIdTransactionHelper(const std::string& url,
11230 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0611231 HttpRequestInfo request;
11232 request.method = "GET";
11233 request.url = GURL(url);
Ramin Halavatib5e433e62018-02-07 07:41:1011234 request.traffic_annotation =
11235 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0611236
bnc691fda62016-08-12 00:43:1611237 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2711238
[email protected]49639fa2011-12-20 23:22:4111239 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0611240
11241 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2011242 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0611243}
11244
[email protected]448d4ca52012-03-04 04:12:2311245} // namespace
11246
Matt Menkef6edce752019-03-19 17:21:5611247TEST_F(HttpNetworkTransactionTest, GroupIdForDirectConnections) {
11248 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311249 {
Matt Menkef6edce752019-03-19 17:21:5611250 "", // unused
11251 "http://www.example.org/direct",
11252 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11253 ClientSocketPool::SocketType::kHttp,
11254 false /* privacy_mode */),
11255 false,
bncce36dca22015-04-21 22:11:2311256 },
11257 {
Matt Menkef6edce752019-03-19 17:21:5611258 "", // unused
11259 "http://[2001:1418:13:1::25]/direct",
11260 ClientSocketPool::GroupId(HostPortPair("2001:1418:13:1::25", 80),
11261 ClientSocketPool::SocketType::kHttp,
11262 false /* privacy_mode */),
11263 false,
bncce36dca22015-04-21 22:11:2311264 },
[email protected]04e5be32009-06-26 20:00:3111265
bncce36dca22015-04-21 22:11:2311266 // SSL Tests
11267 {
Matt Menkef6edce752019-03-19 17:21:5611268 "", // unused
11269 "https://www.example.org/direct_ssl",
11270 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11271 ClientSocketPool::SocketType::kSsl,
11272 false /* privacy_mode */),
11273 true,
bncce36dca22015-04-21 22:11:2311274 },
11275 {
Matt Menkef6edce752019-03-19 17:21:5611276 "", // unused
11277 "https://[2001:1418:13:1::25]/direct",
11278 ClientSocketPool::GroupId(HostPortPair("2001:1418:13:1::25", 443),
11279 ClientSocketPool::SocketType::kSsl,
11280 false /* privacy_mode */),
11281 true,
bncce36dca22015-04-21 22:11:2311282 },
11283 {
Matt Menkef6edce752019-03-19 17:21:5611284 "", // unused
11285 "https://host.with.alternate/direct",
11286 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11287 ClientSocketPool::SocketType::kSsl,
11288 false /* privacy_mode */),
11289 true,
bncce36dca22015-04-21 22:11:2311290 },
[email protected]2d731a32010-04-29 01:04:0611291 };
[email protected]2ff8b312010-04-26 22:20:5411292
Avi Drissman4365a4782018-12-28 19:26:2411293 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911294 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911295 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11296 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911297 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611298 SetupSessionForGroupIdTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611299
mmenkee65e7af2015-10-13 17:16:4211300 HttpNetworkSessionPeer peer(session.get());
Matt Menkef6edce752019-03-19 17:21:5611301 CaptureGroupIdTransportSocketPool* transport_conn_pool =
Matt Menked6fd2a52019-03-20 06:14:3611302 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911303 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011304 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
11305 base::WrapUnique(transport_conn_pool));
dchengc7eeda422015-12-26 03:56:4811306 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611307
11308 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611309 GroupIdTransactionHelper(tests[i].url, session.get()));
11310 EXPECT_EQ(tests[i].expected_group_id,
11311 transport_conn_pool->last_group_id_received());
Matt Menke9d5e2c92019-02-05 01:42:2311312 EXPECT_TRUE(transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0611313 }
[email protected]2d731a32010-04-29 01:04:0611314}
11315
Matt Menkef6edce752019-03-19 17:21:5611316TEST_F(HttpNetworkTransactionTest, GroupIdForHTTPProxyConnections) {
11317 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311318 {
Matt Menke4802de62019-03-08 22:47:5011319 "http_proxy",
11320 "http://www.example.org/http_proxy_normal",
Matt Menkef6edce752019-03-19 17:21:5611321 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11322 ClientSocketPool::SocketType::kHttp,
11323 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011324 false,
bncce36dca22015-04-21 22:11:2311325 },
[email protected]2d731a32010-04-29 01:04:0611326
bncce36dca22015-04-21 22:11:2311327 // SSL Tests
11328 {
Matt Menke4802de62019-03-08 22:47:5011329 "http_proxy",
11330 "https://www.example.org/http_connect_ssl",
Matt Menkef6edce752019-03-19 17:21:5611331 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11332 ClientSocketPool::SocketType::kSsl,
11333 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011334 true,
bncce36dca22015-04-21 22:11:2311335 },
[email protected]af3490e2010-10-16 21:02:2911336
bncce36dca22015-04-21 22:11:2311337 {
Matt Menke4802de62019-03-08 22:47:5011338 "http_proxy",
11339 "https://host.with.alternate/direct",
Matt Menkef6edce752019-03-19 17:21:5611340 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11341 ClientSocketPool::SocketType::kSsl,
11342 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011343 true,
bncce36dca22015-04-21 22:11:2311344 },
[email protected]45499252013-01-23 17:12:5611345
bncce36dca22015-04-21 22:11:2311346 {
Matt Menke4802de62019-03-08 22:47:5011347 "http_proxy",
11348 "ftp://ftp.google.com/http_proxy_normal",
Matt Menkef6edce752019-03-19 17:21:5611349 ClientSocketPool::GroupId(HostPortPair("ftp.google.com", 21),
11350 ClientSocketPool::SocketType::kFtp,
11351 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011352 false,
bncce36dca22015-04-21 22:11:2311353 },
[email protected]2d731a32010-04-29 01:04:0611354 };
11355
Avi Drissman4365a4782018-12-28 19:26:2411356 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911357 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911358 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11359 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911360 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611361 SetupSessionForGroupIdTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611362
mmenkee65e7af2015-10-13 17:16:4211363 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0611364
Matt Menkee8648fa2019-01-17 16:47:0711365 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11366 HostPortPair("http_proxy", 80));
Matt Menkef6edce752019-03-19 17:21:5611367 CaptureGroupIdTransportSocketPool* http_proxy_pool =
Matt Menked6fd2a52019-03-20 06:14:3611368 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911369 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011370 mock_pool_manager->SetSocketPool(proxy_server,
11371 base::WrapUnique(http_proxy_pool));
dchengc7eeda422015-12-26 03:56:4811372 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611373
11374 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611375 GroupIdTransactionHelper(tests[i].url, session.get()));
11376 EXPECT_EQ(tests[i].expected_group_id,
11377 http_proxy_pool->last_group_id_received());
[email protected]2d731a32010-04-29 01:04:0611378 }
[email protected]2d731a32010-04-29 01:04:0611379}
11380
Matt Menkef6edce752019-03-19 17:21:5611381TEST_F(HttpNetworkTransactionTest, GroupIdForSOCKSConnections) {
11382 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311383 {
Matt Menke4802de62019-03-08 22:47:5011384 "socks4://socks_proxy:1080",
11385 "http://www.example.org/socks4_direct",
Matt Menkef6edce752019-03-19 17:21:5611386 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11387 ClientSocketPool::SocketType::kHttp,
11388 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011389 false,
bncce36dca22015-04-21 22:11:2311390 },
11391 {
Matt Menke4802de62019-03-08 22:47:5011392 "socks5://socks_proxy:1080",
11393 "http://www.example.org/socks5_direct",
Matt Menkef6edce752019-03-19 17:21:5611394 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11395 ClientSocketPool::SocketType::kHttp,
11396 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011397 false,
bncce36dca22015-04-21 22:11:2311398 },
[email protected]2d731a32010-04-29 01:04:0611399
bncce36dca22015-04-21 22:11:2311400 // SSL Tests
11401 {
Matt Menke4802de62019-03-08 22:47:5011402 "socks4://socks_proxy:1080",
11403 "https://www.example.org/socks4_ssl",
Matt Menkef6edce752019-03-19 17:21:5611404 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11405 ClientSocketPool::SocketType::kSsl,
11406 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011407 true,
bncce36dca22015-04-21 22:11:2311408 },
11409 {
Matt Menke4802de62019-03-08 22:47:5011410 "socks5://socks_proxy:1080",
11411 "https://www.example.org/socks5_ssl",
Matt Menkef6edce752019-03-19 17:21:5611412 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11413 ClientSocketPool::SocketType::kSsl,
11414 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011415 true,
bncce36dca22015-04-21 22:11:2311416 },
[email protected]af3490e2010-10-16 21:02:2911417
bncce36dca22015-04-21 22:11:2311418 {
Matt Menke4802de62019-03-08 22:47:5011419 "socks4://socks_proxy:1080",
11420 "https://host.with.alternate/direct",
Matt Menkef6edce752019-03-19 17:21:5611421 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11422 ClientSocketPool::SocketType::kSsl,
11423 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011424 true,
bncce36dca22015-04-21 22:11:2311425 },
[email protected]04e5be32009-06-26 20:00:3111426 };
11427
Avi Drissman4365a4782018-12-28 19:26:2411428 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911429 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911430 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11431 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911432 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611433 SetupSessionForGroupIdTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0211434
mmenkee65e7af2015-10-13 17:16:4211435 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3111436
Matt Menkee8648fa2019-01-17 16:47:0711437 ProxyServer proxy_server(
11438 ProxyServer::FromURI(tests[i].proxy_server, ProxyServer::SCHEME_HTTP));
11439 ASSERT_TRUE(proxy_server.is_valid());
Matt Menkef6edce752019-03-19 17:21:5611440 CaptureGroupIdTransportSocketPool* socks_conn_pool =
Matt Menked6fd2a52019-03-20 06:14:3611441 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911442 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011443 mock_pool_manager->SetSocketPool(proxy_server,
11444 base::WrapUnique(socks_conn_pool));
dchengc7eeda422015-12-26 03:56:4811445 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3111446
bnc691fda62016-08-12 00:43:1611447 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3111448
[email protected]2d731a32010-04-29 01:04:0611449 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611450 GroupIdTransactionHelper(tests[i].url, session.get()));
11451 EXPECT_EQ(tests[i].expected_group_id,
11452 socks_conn_pool->last_group_id_received());
[email protected]04e5be32009-06-26 20:00:3111453 }
11454}
11455
bncd16676a2016-07-20 16:23:0111456TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2711457 HttpRequestInfo request;
11458 request.method = "GET";
bncce36dca22015-04-21 22:11:2311459 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011460 request.traffic_annotation =
11461 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711462
Ramin Halavatica8d5252018-03-12 05:33:4911463 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11464 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3211465
[email protected]69719062010-01-05 20:09:2111466 // This simulates failure resolving all hostnames; that means we will fail
11467 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0711468 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3211469
danakj1fd259a02016-04-16 03:17:0911470 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611471 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2511472
[email protected]49639fa2011-12-20 23:22:4111473 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2511474
tfarina42834112016-09-22 13:38:2011475 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111476 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2511477
[email protected]9172a982009-06-06 00:30:2511478 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111479 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2511480}
11481
[email protected]0877e3d2009-10-17 22:29:5711482// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0111483TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5711484 HttpRequestInfo request;
11485 request.method = "GET";
11486 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1011487 request.traffic_annotation =
11488 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711489
11490 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0611491 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711492 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111493 StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
[email protected]bb88e1d32013-05-03 23:11:0711494 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911495 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711496
[email protected]49639fa2011-12-20 23:22:4111497 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711498
bnc691fda62016-08-12 00:43:1611499 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711500
tfarina42834112016-09-22 13:38:2011501 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111502 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711503
11504 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111505 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5911506
11507 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611508 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911509 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711510}
11511
zmo9528c9f42015-08-04 22:12:0811512// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0111513TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5711514 HttpRequestInfo request;
11515 request.method = "GET";
11516 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1011517 request.traffic_annotation =
11518 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711519
11520 MockRead data_reads[] = {
11521 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0611522 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711523 };
11524
Ryan Sleevib8d7ea02018-05-07 20:01:0111525 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711526 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911527 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711528
[email protected]49639fa2011-12-20 23:22:4111529 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711530
bnc691fda62016-08-12 00:43:1611531 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711532
tfarina42834112016-09-22 13:38:2011533 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111534 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711535
11536 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111537 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811538
bnc691fda62016-08-12 00:43:1611539 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211540 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0811541
wezca1070932016-05-26 20:30:5211542 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0811543 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11544
11545 std::string response_data;
bnc691fda62016-08-12 00:43:1611546 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111547 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811548 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5911549
11550 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611551 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911552 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711553}
11554
11555// Make sure that a dropped connection while draining the body for auth
11556// restart does the right thing.
bncd16676a2016-07-20 16:23:0111557TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5711558 HttpRequestInfo request;
11559 request.method = "GET";
bncce36dca22015-04-21 22:11:2311560 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011561 request.traffic_annotation =
11562 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711563
11564 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311565 MockWrite(
11566 "GET / HTTP/1.1\r\n"
11567 "Host: www.example.org\r\n"
11568 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711569 };
11570
11571 MockRead data_reads1[] = {
11572 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
11573 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
11574 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11575 MockRead("Content-Length: 14\r\n\r\n"),
11576 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0611577 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711578 };
11579
Ryan Sleevib8d7ea02018-05-07 20:01:0111580 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0711581 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5711582
bnc691fda62016-08-12 00:43:1611583 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5711584 // be issuing -- the final header line contains the credentials.
11585 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311586 MockWrite(
11587 "GET / HTTP/1.1\r\n"
11588 "Host: www.example.org\r\n"
11589 "Connection: keep-alive\r\n"
11590 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711591 };
11592
11593 // Lastly, the server responds with the actual content.
11594 MockRead data_reads2[] = {
11595 MockRead("HTTP/1.1 200 OK\r\n"),
11596 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11597 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611598 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711599 };
11600
Ryan Sleevib8d7ea02018-05-07 20:01:0111601 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:0711602 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0911603 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711604
[email protected]49639fa2011-12-20 23:22:4111605 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5711606
bnc691fda62016-08-12 00:43:1611607 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011608
tfarina42834112016-09-22 13:38:2011609 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111610 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711611
11612 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111613 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711614
bnc691fda62016-08-12 00:43:1611615 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211616 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411617 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5711618
[email protected]49639fa2011-12-20 23:22:4111619 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5711620
bnc691fda62016-08-12 00:43:1611621 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0111622 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711623
11624 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111625 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711626
bnc691fda62016-08-12 00:43:1611627 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211628 ASSERT_TRUE(response);
11629 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5711630 EXPECT_EQ(100, response->headers->GetContentLength());
11631}
11632
11633// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0111634TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4911635 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11636 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711637
11638 HttpRequestInfo request;
11639 request.method = "GET";
bncce36dca22015-04-21 22:11:2311640 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011641 request.traffic_annotation =
11642 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711643
11644 MockRead proxy_reads[] = {
11645 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0611646 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5711647 };
11648
Ryan Sleevib8d7ea02018-05-07 20:01:0111649 StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
[email protected]8ddf8322012-02-23 18:08:0611650 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5711651
[email protected]bb88e1d32013-05-03 23:11:0711652 session_deps_.socket_factory->AddSocketDataProvider(&data);
11653 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5711654
[email protected]49639fa2011-12-20 23:22:4111655 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711656
[email protected]bb88e1d32013-05-03 23:11:0711657 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5711658
danakj1fd259a02016-04-16 03:17:0911659 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611660 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711661
tfarina42834112016-09-22 13:38:2011662 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111663 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711664
11665 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111666 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5711667}
11668
bncd16676a2016-07-20 16:23:0111669TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4611670 HttpRequestInfo request;
11671 request.method = "GET";
bncce36dca22015-04-21 22:11:2311672 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011673 request.traffic_annotation =
11674 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4611675
danakj1fd259a02016-04-16 03:17:0911676 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611677 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2711678
[email protected]e22e1362009-11-23 21:31:1211679 MockRead data_reads[] = {
11680 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611681 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1211682 };
[email protected]9492e4a2010-02-24 00:58:4611683
Ryan Sleevib8d7ea02018-05-07 20:01:0111684 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711685 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4611686
[email protected]49639fa2011-12-20 23:22:4111687 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4611688
tfarina42834112016-09-22 13:38:2011689 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4611691
robpercival214763f2016-07-01 23:27:0111692 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4611693
bnc691fda62016-08-12 00:43:1611694 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211695 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4611696
wezca1070932016-05-26 20:30:5211697 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4611698 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11699
11700 std::string response_data;
bnc691fda62016-08-12 00:43:1611701 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111702 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1211703}
11704
bncd16676a2016-07-20 16:23:0111705TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1511706 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5211707 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1411708 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2111709 UploadFileElementReader::ScopedOverridingContentLengthForTests
11710 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3311711
danakj1fd259a02016-04-16 03:17:0911712 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911713 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411714 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0711715 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211716 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711717
11718 HttpRequestInfo request;
11719 request.method = "POST";
bncce36dca22015-04-21 22:11:2311720 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711721 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1011722 request.traffic_annotation =
11723 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711724
danakj1fd259a02016-04-16 03:17:0911725 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611726 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3311727
11728 MockRead data_reads[] = {
11729 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11730 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611731 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3311732 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111733 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711734 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3311735
[email protected]49639fa2011-12-20 23:22:4111736 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3311737
tfarina42834112016-09-22 13:38:2011738 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111739 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3311740
11741 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111742 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3311743
bnc691fda62016-08-12 00:43:1611744 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211745 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3311746
maksim.sisove869bf52016-06-23 17:11:5211747 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3311748
[email protected]dd3aa792013-07-16 19:10:2311749 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3311750}
11751
bncd16676a2016-07-20 16:23:0111752TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1511753 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5211754 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3611755 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4811756 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
11757 base::WriteFile(temp_file, temp_file_content.c_str(),
11758 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1111759 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3611760
danakj1fd259a02016-04-16 03:17:0911761 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911762 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411763 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0711764 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211765 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711766
11767 HttpRequestInfo request;
11768 request.method = "POST";
bncce36dca22015-04-21 22:11:2311769 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711770 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1011771 request.traffic_annotation =
11772 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711773
[email protected]999dd8c2013-11-12 06:45:5411774 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0911775 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611776 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3611777
Ryan Sleevib8d7ea02018-05-07 20:01:0111778 StaticSocketDataProvider data;
[email protected]bb88e1d32013-05-03 23:11:0711779 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3611780
[email protected]49639fa2011-12-20 23:22:4111781 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3611782
tfarina42834112016-09-22 13:38:2011783 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111784 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3611785
11786 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111787 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3611788
[email protected]dd3aa792013-07-16 19:10:2311789 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3611790}
11791
bncd16676a2016-07-20 16:23:0111792TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0311793 class FakeUploadElementReader : public UploadElementReader {
11794 public:
Chris Watkins7a41d3552017-12-01 02:13:2711795 FakeUploadElementReader() = default;
11796 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0311797
Matt Menkecc1d3a902018-02-05 18:27:3311798 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0311799
11800 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3311801 int Init(CompletionOnceCallback callback) override {
11802 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0311803 return ERR_IO_PENDING;
11804 }
avibf0746c2015-12-09 19:53:1411805 uint64_t GetContentLength() const override { return 0; }
11806 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2011807 int Read(IOBuffer* buf,
11808 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3311809 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0311810 return ERR_FAILED;
11811 }
11812
11813 private:
Matt Menkecc1d3a902018-02-05 18:27:3311814 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0311815 };
11816
11817 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0911818 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11819 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2211820 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0311821
11822 HttpRequestInfo request;
11823 request.method = "POST";
bncce36dca22015-04-21 22:11:2311824 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0311825 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1011826 request.traffic_annotation =
11827 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0311828
danakj1fd259a02016-04-16 03:17:0911829 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811830 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911831 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0311832
11833 StaticSocketDataProvider data;
11834 session_deps_.socket_factory->AddSocketDataProvider(&data);
11835
11836 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2011837 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111838 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5511839 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0311840
11841 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3311842 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
11843 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0311844
11845 // Return Init()'s result after the transaction gets destroyed.
11846 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3311847 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0311848}
11849
[email protected]aeefc9e82010-02-19 16:18:2711850// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0111851TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2711852 HttpRequestInfo request;
11853 request.method = "GET";
bncce36dca22015-04-21 22:11:2311854 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011855 request.traffic_annotation =
11856 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2711857
11858 // First transaction will request a resource and receive a Basic challenge
11859 // with realm="first_realm".
11860 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311861 MockWrite(
11862 "GET / HTTP/1.1\r\n"
11863 "Host: www.example.org\r\n"
11864 "Connection: keep-alive\r\n"
11865 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711866 };
11867 MockRead data_reads1[] = {
11868 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11869 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11870 "\r\n"),
11871 };
11872
bnc691fda62016-08-12 00:43:1611873 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2711874 // for first_realm. The server will reject and provide a challenge with
11875 // second_realm.
11876 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311877 MockWrite(
11878 "GET / HTTP/1.1\r\n"
11879 "Host: www.example.org\r\n"
11880 "Connection: keep-alive\r\n"
11881 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
11882 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711883 };
11884 MockRead data_reads2[] = {
11885 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11886 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
11887 "\r\n"),
11888 };
11889
11890 // This again fails, and goes back to first_realm. Make sure that the
11891 // entry is removed from cache.
11892 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2311893 MockWrite(
11894 "GET / HTTP/1.1\r\n"
11895 "Host: www.example.org\r\n"
11896 "Connection: keep-alive\r\n"
11897 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
11898 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711899 };
11900 MockRead data_reads3[] = {
11901 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11902 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11903 "\r\n"),
11904 };
11905
11906 // Try one last time (with the correct password) and get the resource.
11907 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2311908 MockWrite(
11909 "GET / HTTP/1.1\r\n"
11910 "Host: www.example.org\r\n"
11911 "Connection: keep-alive\r\n"
11912 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
11913 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711914 };
11915 MockRead data_reads4[] = {
11916 MockRead("HTTP/1.1 200 OK\r\n"
11917 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5011918 "Content-Length: 5\r\n"
11919 "\r\n"
11920 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2711921 };
11922
Ryan Sleevib8d7ea02018-05-07 20:01:0111923 StaticSocketDataProvider data1(data_reads1, data_writes1);
11924 StaticSocketDataProvider data2(data_reads2, data_writes2);
11925 StaticSocketDataProvider data3(data_reads3, data_writes3);
11926 StaticSocketDataProvider data4(data_reads4, data_writes4);
[email protected]bb88e1d32013-05-03 23:11:0711927 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11928 session_deps_.socket_factory->AddSocketDataProvider(&data2);
11929 session_deps_.socket_factory->AddSocketDataProvider(&data3);
11930 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2711931
[email protected]49639fa2011-12-20 23:22:4111932 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2711933
danakj1fd259a02016-04-16 03:17:0911934 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611935 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011936
[email protected]aeefc9e82010-02-19 16:18:2711937 // Issue the first request with Authorize headers. There should be a
11938 // password prompt for first_realm waiting to be filled in after the
11939 // transaction completes.
tfarina42834112016-09-22 13:38:2011940 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111941 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711942 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111943 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611944 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211945 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411946 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211947 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411948 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311949 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411950 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911951 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711952
11953 // Issue the second request with an incorrect password. There should be a
11954 // password prompt for second_realm waiting to be filled in after the
11955 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4111956 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1611957 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
11958 callback2.callback());
robpercival214763f2016-07-01 23:27:0111959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711960 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111961 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611962 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211963 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411964 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211965 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411966 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311967 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411968 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911969 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711970
11971 // Issue the third request with another incorrect password. There should be
11972 // a password prompt for first_realm waiting to be filled in. If the password
11973 // prompt is not present, it indicates that the HttpAuthCacheEntry for
11974 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4111975 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1611976 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
11977 callback3.callback());
robpercival214763f2016-07-01 23:27:0111978 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711979 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0111980 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611981 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211982 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0411983 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5211984 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411985 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311986 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411987 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911988 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711989
11990 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4111991 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1611992 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
11993 callback4.callback());
robpercival214763f2016-07-01 23:27:0111994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711995 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0111996 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611997 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211998 ASSERT_TRUE(response);
11999 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2712000}
12001
Bence Béky230ac612017-08-30 19:17:0812002// Regression test for https://crbug.com/754395.
12003TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
12004 MockRead data_reads[] = {
12005 MockRead("HTTP/1.1 200 OK\r\n"),
12006 MockRead(kAlternativeServiceHttpHeader),
12007 MockRead("\r\n"),
12008 MockRead("hello world"),
12009 MockRead(SYNCHRONOUS, OK),
12010 };
12011
12012 HttpRequestInfo request;
12013 request.method = "GET";
12014 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012015 request.traffic_annotation =
12016 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0812017
Ryan Sleevib8d7ea02018-05-07 20:01:0112018 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:0812019 session_deps_.socket_factory->AddSocketDataProvider(&data);
12020
12021 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912022 ssl.ssl_info.cert =
12023 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12024 ASSERT_TRUE(ssl.ssl_info.cert);
12025 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0812026 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12027
12028 TestCompletionCallback callback;
12029
12030 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12031 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12032
12033 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
12034 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12035
12036 url::SchemeHostPort test_server(request.url);
12037 HttpServerProperties* http_server_properties =
12038 session->http_server_properties();
12039 EXPECT_TRUE(
12040 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
12041
12042 EXPECT_THAT(callback.WaitForResult(), IsOk());
12043
12044 const HttpResponseInfo* response = trans.GetResponseInfo();
12045 ASSERT_TRUE(response);
12046 ASSERT_TRUE(response->headers);
12047 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12048 EXPECT_FALSE(response->was_fetched_via_spdy);
12049 EXPECT_FALSE(response->was_alpn_negotiated);
12050
12051 std::string response_data;
12052 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
12053 EXPECT_EQ("hello world", response_data);
12054
12055 EXPECT_TRUE(
12056 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
12057}
12058
bncd16676a2016-07-20 16:23:0112059TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5212060 MockRead data_reads[] = {
12061 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312062 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212063 MockRead("\r\n"),
12064 MockRead("hello world"),
12065 MockRead(SYNCHRONOUS, OK),
12066 };
12067
12068 HttpRequestInfo request;
12069 request.method = "GET";
bncb26024382016-06-29 02:39:4512070 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012071 request.traffic_annotation =
12072 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5212073
Ryan Sleevib8d7ea02018-05-07 20:01:0112074 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5212075 session_deps_.socket_factory->AddSocketDataProvider(&data);
12076
bncb26024382016-06-29 02:39:4512077 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912078 ssl.ssl_info.cert =
12079 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12080 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512081 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12082
bncc958faa2015-07-31 18:14:5212083 TestCompletionCallback callback;
12084
danakj1fd259a02016-04-16 03:17:0912085 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612086 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5212087
tfarina42834112016-09-22 13:38:2012088 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112089 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5212090
bncb26024382016-06-29 02:39:4512091 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4012092 HttpServerProperties* http_server_properties =
12093 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412094 EXPECT_TRUE(
12095 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5212096
robpercival214763f2016-07-01 23:27:0112097 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5212098
bnc691fda62016-08-12 00:43:1612099 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212100 ASSERT_TRUE(response);
12101 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5212102 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12103 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212104 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212105
12106 std::string response_data;
bnc691fda62016-08-12 00:43:1612107 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212108 EXPECT_EQ("hello world", response_data);
12109
zhongyic4de03032017-05-19 04:07:3412110 AlternativeServiceInfoVector alternative_service_info_vector =
12111 http_server_properties->GetAlternativeServiceInfos(test_server);
12112 ASSERT_EQ(1u, alternative_service_info_vector.size());
12113 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
12114 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412115 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5212116}
12117
bnce3dd56f2016-06-01 10:37:1112118// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0112119TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112120 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1112121 MockRead data_reads[] = {
12122 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312123 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1112124 MockRead("\r\n"),
12125 MockRead("hello world"),
12126 MockRead(SYNCHRONOUS, OK),
12127 };
12128
12129 HttpRequestInfo request;
12130 request.method = "GET";
12131 request.url = GURL("http://www.example.org/");
12132 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012133 request.traffic_annotation =
12134 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112135
Ryan Sleevib8d7ea02018-05-07 20:01:0112136 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112137 session_deps_.socket_factory->AddSocketDataProvider(&data);
12138
12139 TestCompletionCallback callback;
12140
12141 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612142 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112143
12144 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4012145 HttpServerProperties* http_server_properties =
12146 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412147 EXPECT_TRUE(
12148 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112149
tfarina42834112016-09-22 13:38:2012150 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112151 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12152 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1112153
bnc691fda62016-08-12 00:43:1612154 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1112155 ASSERT_TRUE(response);
12156 ASSERT_TRUE(response->headers);
12157 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12158 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212159 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1112160
12161 std::string response_data;
bnc691fda62016-08-12 00:43:1612162 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1112163 EXPECT_EQ("hello world", response_data);
12164
zhongyic4de03032017-05-19 04:07:3412165 EXPECT_TRUE(
12166 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112167}
12168
bnca86731e2017-04-17 12:31:2812169// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2512170// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0112171TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2512172 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2812173 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4512174
bnc8bef8da22016-05-30 01:28:2512175 HttpRequestInfo request;
12176 request.method = "GET";
bncb26024382016-06-29 02:39:4512177 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2512178 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012179 request.traffic_annotation =
12180 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2512181
12182 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12183 StaticSocketDataProvider first_data;
12184 first_data.set_connect_data(mock_connect);
12185 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512186 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612187 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512188 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2512189
12190 MockRead data_reads[] = {
12191 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12192 MockRead(ASYNC, OK),
12193 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112194 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnc8bef8da22016-05-30 01:28:2512195 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12196
12197 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12198
bnc525e175a2016-06-20 12:36:4012199 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2512200 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112201 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
12202 444);
bnc8bef8da22016-05-30 01:28:2512203 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112204 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2512205 url::SchemeHostPort(request.url), alternative_service, expiration);
12206
bnc691fda62016-08-12 00:43:1612207 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2512208 TestCompletionCallback callback;
12209
tfarina42834112016-09-22 13:38:2012210 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2512211 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112212 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2512213}
12214
bnce3dd56f2016-06-01 10:37:1112215// Regression test for https://crbug.com/615497:
12216// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0112217TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112218 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1112219 HttpRequestInfo request;
12220 request.method = "GET";
12221 request.url = GURL("http://www.example.org/");
12222 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012223 request.traffic_annotation =
12224 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112225
12226 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12227 StaticSocketDataProvider first_data;
12228 first_data.set_connect_data(mock_connect);
12229 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
12230
12231 MockRead data_reads[] = {
12232 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12233 MockRead(ASYNC, OK),
12234 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112235 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112236 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12237
12238 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12239
bnc525e175a2016-06-20 12:36:4012240 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1112241 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112242 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1112243 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112244 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1112245 url::SchemeHostPort(request.url), alternative_service, expiration);
12246
bnc691fda62016-08-12 00:43:1612247 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112248 TestCompletionCallback callback;
12249
tfarina42834112016-09-22 13:38:2012250 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1112251 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112252 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1112253}
12254
bncd16676a2016-07-20 16:23:0112255TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0812256 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0912257 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012258 HttpServerProperties* http_server_properties =
12259 session->http_server_properties();
bncb26024382016-06-29 02:39:4512260 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2112261 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0812262 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112263 http_server_properties->SetQuicAlternativeService(
12264 test_server, alternative_service, expiration,
12265 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3412266 EXPECT_EQ(
12267 1u,
12268 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0812269
12270 // Send a clear header.
12271 MockRead data_reads[] = {
12272 MockRead("HTTP/1.1 200 OK\r\n"),
12273 MockRead("Alt-Svc: clear\r\n"),
12274 MockRead("\r\n"),
12275 MockRead("hello world"),
12276 MockRead(SYNCHRONOUS, OK),
12277 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112278 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnc4f575852015-10-14 18:35:0812279 session_deps_.socket_factory->AddSocketDataProvider(&data);
12280
bncb26024382016-06-29 02:39:4512281 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912282 ssl.ssl_info.cert =
12283 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12284 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512285 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12286
bnc4f575852015-10-14 18:35:0812287 HttpRequestInfo request;
12288 request.method = "GET";
bncb26024382016-06-29 02:39:4512289 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012290 request.traffic_annotation =
12291 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0812292
12293 TestCompletionCallback callback;
12294
bnc691fda62016-08-12 00:43:1612295 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0812296
tfarina42834112016-09-22 13:38:2012297 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112298 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0812299
bnc691fda62016-08-12 00:43:1612300 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212301 ASSERT_TRUE(response);
12302 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0812303 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12304 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212305 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0812306
12307 std::string response_data;
bnc691fda62016-08-12 00:43:1612308 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0812309 EXPECT_EQ("hello world", response_data);
12310
zhongyic4de03032017-05-19 04:07:3412311 EXPECT_TRUE(
12312 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0812313}
12314
bncd16676a2016-07-20 16:23:0112315TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5212316 MockRead data_reads[] = {
12317 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312318 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
12319 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5212320 MockRead("hello world"),
12321 MockRead(SYNCHRONOUS, OK),
12322 };
12323
12324 HttpRequestInfo request;
12325 request.method = "GET";
bncb26024382016-06-29 02:39:4512326 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012327 request.traffic_annotation =
12328 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5212329
Ryan Sleevib8d7ea02018-05-07 20:01:0112330 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5212331 session_deps_.socket_factory->AddSocketDataProvider(&data);
12332
bncb26024382016-06-29 02:39:4512333 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912334 ssl.ssl_info.cert =
12335 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12336 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512337 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12338
bncc958faa2015-07-31 18:14:5212339 TestCompletionCallback callback;
12340
danakj1fd259a02016-04-16 03:17:0912341 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612342 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5212343
tfarina42834112016-09-22 13:38:2012344 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112345 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5212346
bncb26024382016-06-29 02:39:4512347 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4012348 HttpServerProperties* http_server_properties =
12349 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412350 EXPECT_TRUE(
12351 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5212352
robpercival214763f2016-07-01 23:27:0112353 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5212354
bnc691fda62016-08-12 00:43:1612355 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212356 ASSERT_TRUE(response);
12357 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5212358 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12359 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212360 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212361
12362 std::string response_data;
bnc691fda62016-08-12 00:43:1612363 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212364 EXPECT_EQ("hello world", response_data);
12365
zhongyic4de03032017-05-19 04:07:3412366 AlternativeServiceInfoVector alternative_service_info_vector =
12367 http_server_properties->GetAlternativeServiceInfos(test_server);
12368 ASSERT_EQ(2u, alternative_service_info_vector.size());
12369
12370 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
12371 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412372 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412373 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
12374 1234);
12375 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5412376 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5212377}
12378
bncd16676a2016-07-20 16:23:0112379TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612380 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212381 HostPortPair alternative("alternative.example.org", 443);
12382 std::string origin_url = "https://origin.example.org:443";
12383 std::string alternative_url = "https://alternative.example.org:443";
12384
12385 // Negotiate HTTP/1.1 with alternative.example.org.
12386 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612387 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212388 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12389
12390 // HTTP/1.1 data for request.
12391 MockWrite http_writes[] = {
12392 MockWrite("GET / HTTP/1.1\r\n"
12393 "Host: alternative.example.org\r\n"
12394 "Connection: keep-alive\r\n\r\n"),
12395 };
12396
12397 MockRead http_reads[] = {
12398 MockRead("HTTP/1.1 200 OK\r\n"
12399 "Content-Type: text/html; charset=iso-8859-1\r\n"
12400 "Content-Length: 40\r\n\r\n"
12401 "first HTTP/1.1 response from alternative"),
12402 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112403 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212404 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12405
12406 StaticSocketDataProvider data_refused;
12407 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12408 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12409
zhongyi3d4a55e72016-04-22 20:36:4612410 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0912411 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012412 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212413 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112414 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0212415 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112416 http_server_properties->SetQuicAlternativeService(
12417 server, alternative_service, expiration,
12418 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0212419 // Mark the QUIC alternative service as broken.
12420 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
12421
zhongyi48704c182015-12-07 07:52:0212422 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612423 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212424 request.method = "GET";
12425 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1012426 request.traffic_annotation =
12427 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12428
zhongyi48704c182015-12-07 07:52:0212429 TestCompletionCallback callback;
12430 NetErrorDetails details;
12431 EXPECT_FALSE(details.quic_broken);
12432
tfarina42834112016-09-22 13:38:2012433 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612434 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212435 EXPECT_TRUE(details.quic_broken);
12436}
12437
bncd16676a2016-07-20 16:23:0112438TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612439 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212440 HostPortPair alternative1("alternative1.example.org", 443);
12441 HostPortPair alternative2("alternative2.example.org", 443);
12442 std::string origin_url = "https://origin.example.org:443";
12443 std::string alternative_url1 = "https://alternative1.example.org:443";
12444 std::string alternative_url2 = "https://alternative2.example.org:443";
12445
12446 // Negotiate HTTP/1.1 with alternative1.example.org.
12447 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612448 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212449 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12450
12451 // HTTP/1.1 data for request.
12452 MockWrite http_writes[] = {
12453 MockWrite("GET / HTTP/1.1\r\n"
12454 "Host: alternative1.example.org\r\n"
12455 "Connection: keep-alive\r\n\r\n"),
12456 };
12457
12458 MockRead http_reads[] = {
12459 MockRead("HTTP/1.1 200 OK\r\n"
12460 "Content-Type: text/html; charset=iso-8859-1\r\n"
12461 "Content-Length: 40\r\n\r\n"
12462 "first HTTP/1.1 response from alternative1"),
12463 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112464 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212465 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12466
12467 StaticSocketDataProvider data_refused;
12468 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12469 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12470
danakj1fd259a02016-04-16 03:17:0912471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012472 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212473 session->http_server_properties();
12474
zhongyi3d4a55e72016-04-22 20:36:4612475 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0212476 AlternativeServiceInfoVector alternative_service_info_vector;
12477 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
12478
bnc3472afd2016-11-17 15:27:2112479 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2112480 alternative_service_info_vector.push_back(
12481 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12482 alternative_service1, expiration,
12483 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2112484 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2112485 alternative_service_info_vector.push_back(
12486 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12487 alternative_service2, expiration,
12488 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0212489
12490 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4612491 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0212492
12493 // Mark one of the QUIC alternative service as broken.
12494 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3412495 EXPECT_EQ(2u,
12496 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0212497
zhongyi48704c182015-12-07 07:52:0212498 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612499 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212500 request.method = "GET";
12501 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1012502 request.traffic_annotation =
12503 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12504
zhongyi48704c182015-12-07 07:52:0212505 TestCompletionCallback callback;
12506 NetErrorDetails details;
12507 EXPECT_FALSE(details.quic_broken);
12508
tfarina42834112016-09-22 13:38:2012509 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612510 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212511 EXPECT_FALSE(details.quic_broken);
12512}
12513
bncd16676a2016-07-20 16:23:0112514TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4212515 HttpRequestInfo request;
12516 request.method = "GET";
bncb26024382016-06-29 02:39:4512517 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012518 request.traffic_annotation =
12519 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4212520
[email protected]d973e99a2012-02-17 21:02:3612521 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4212522 StaticSocketDataProvider first_data;
12523 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712524 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512525 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612526 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512527 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4212528
12529 MockRead data_reads[] = {
12530 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12531 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612532 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4212533 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112534 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712535 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4212536
danakj1fd259a02016-04-16 03:17:0912537 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4212538
bnc525e175a2016-06-20 12:36:4012539 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312540 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4612541 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1112542 // Port must be < 1024, or the header will be ignored (since initial port was
12543 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2112544 // Port is ignored by MockConnect anyway.
12545 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12546 666);
bnc7dc7e1b42015-07-28 14:43:1212547 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112548 http_server_properties->SetHttp2AlternativeService(
12549 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4212550
bnc691fda62016-08-12 00:43:1612551 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112552 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4212553
tfarina42834112016-09-22 13:38:2012554 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12556 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4212557
bnc691fda62016-08-12 00:43:1612558 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212559 ASSERT_TRUE(response);
12560 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4212561 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12562
12563 std::string response_data;
bnc691fda62016-08-12 00:43:1612564 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4212565 EXPECT_EQ("hello world", response_data);
12566
zhongyic4de03032017-05-19 04:07:3412567 const AlternativeServiceInfoVector alternative_service_info_vector =
12568 http_server_properties->GetAlternativeServiceInfos(server);
12569 ASSERT_EQ(1u, alternative_service_info_vector.size());
12570 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412571 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412572 EXPECT_TRUE(
12573 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4212574}
12575
bnc55ff9da2015-08-19 18:42:3512576// Ensure that we are not allowed to redirect traffic via an alternate protocol
12577// to an unrestricted (port >= 1024) when the original traffic was on a
12578// restricted port (port < 1024). Ensure that we can redirect in all other
12579// cases.
bncd16676a2016-07-20 16:23:0112580TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1112581 HttpRequestInfo restricted_port_request;
12582 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512583 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112584 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012585 restricted_port_request.traffic_annotation =
12586 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112587
[email protected]d973e99a2012-02-17 21:02:3612588 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112589 StaticSocketDataProvider first_data;
12590 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712591 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112592
12593 MockRead data_reads[] = {
12594 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12595 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612596 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112597 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112598 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712599 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512600 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612601 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512602 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112603
danakj1fd259a02016-04-16 03:17:0912604 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112605
bnc525e175a2016-06-20 12:36:4012606 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312607 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112608 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112609 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12610 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212611 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112612 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612613 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012614 expiration);
[email protected]3912662a32011-10-04 00:51:1112615
bnc691fda62016-08-12 00:43:1612616 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112617 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112618
tfarina42834112016-09-22 13:38:2012619 int rv = trans.Start(&restricted_port_request, callback.callback(),
12620 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112621 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112622 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0112623 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1912624}
[email protected]3912662a32011-10-04 00:51:1112625
bnc55ff9da2015-08-19 18:42:3512626// Ensure that we are allowed to redirect traffic via an alternate protocol to
12627// an unrestricted (port >= 1024) when the original traffic was on a restricted
12628// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0112629TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0712630 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1912631
12632 HttpRequestInfo restricted_port_request;
12633 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512634 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1912635 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012636 restricted_port_request.traffic_annotation =
12637 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1912638
12639 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12640 StaticSocketDataProvider first_data;
12641 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712642 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1912643
12644 MockRead data_reads[] = {
12645 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12646 MockRead("hello world"),
12647 MockRead(ASYNC, OK),
12648 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112649 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712650 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512651 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612652 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512653 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1912654
danakj1fd259a02016-04-16 03:17:0912655 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1912656
bnc525e175a2016-06-20 12:36:4012657 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1912658 session->http_server_properties();
12659 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112660 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12661 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212662 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112663 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612664 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012665 expiration);
[email protected]c54c6962013-02-01 04:53:1912666
bnc691fda62016-08-12 00:43:1612667 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1912668 TestCompletionCallback callback;
12669
tfarina42834112016-09-22 13:38:2012670 EXPECT_EQ(ERR_IO_PENDING,
12671 trans.Start(&restricted_port_request, callback.callback(),
12672 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1912673 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0112674 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112675}
12676
bnc55ff9da2015-08-19 18:42:3512677// Ensure that we are not allowed to redirect traffic via an alternate protocol
12678// to an unrestricted (port >= 1024) when the original traffic was on a
12679// restricted port (port < 1024). Ensure that we can redirect in all other
12680// cases.
bncd16676a2016-07-20 16:23:0112681TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1112682 HttpRequestInfo restricted_port_request;
12683 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512684 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112685 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012686 restricted_port_request.traffic_annotation =
12687 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112688
[email protected]d973e99a2012-02-17 21:02:3612689 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112690 StaticSocketDataProvider first_data;
12691 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712692 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112693
12694 MockRead data_reads[] = {
12695 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12696 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612697 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112698 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112699 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712700 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112701
bncb26024382016-06-29 02:39:4512702 SSLSocketDataProvider ssl(ASYNC, OK);
12703 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12704
danakj1fd259a02016-04-16 03:17:0912705 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112706
bnc525e175a2016-06-20 12:36:4012707 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312708 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112709 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112710 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12711 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212712 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112713 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612714 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012715 expiration);
[email protected]3912662a32011-10-04 00:51:1112716
bnc691fda62016-08-12 00:43:1612717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112718 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112719
tfarina42834112016-09-22 13:38:2012720 int rv = trans.Start(&restricted_port_request, callback.callback(),
12721 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112722 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112723 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112724 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112725}
12726
bnc55ff9da2015-08-19 18:42:3512727// Ensure that we are not allowed to redirect traffic via an alternate protocol
12728// to an unrestricted (port >= 1024) when the original traffic was on a
12729// restricted port (port < 1024). Ensure that we can redirect in all other
12730// cases.
bncd16676a2016-07-20 16:23:0112731TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1112732 HttpRequestInfo unrestricted_port_request;
12733 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512734 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112735 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012736 unrestricted_port_request.traffic_annotation =
12737 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112738
[email protected]d973e99a2012-02-17 21:02:3612739 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112740 StaticSocketDataProvider first_data;
12741 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712742 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112743
12744 MockRead data_reads[] = {
12745 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12746 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612747 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112748 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112749 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712750 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512751 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612752 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512753 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112754
danakj1fd259a02016-04-16 03:17:0912755 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112756
bnc525e175a2016-06-20 12:36:4012757 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312758 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112759 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112760 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12761 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212762 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112763 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612764 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012765 expiration);
[email protected]3912662a32011-10-04 00:51:1112766
bnc691fda62016-08-12 00:43:1612767 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112768 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112769
bnc691fda62016-08-12 00:43:1612770 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012771 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112772 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112773 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112774 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112775}
12776
bnc55ff9da2015-08-19 18:42:3512777// Ensure that we are not allowed to redirect traffic via an alternate protocol
12778// to an unrestricted (port >= 1024) when the original traffic was on a
12779// restricted port (port < 1024). Ensure that we can redirect in all other
12780// cases.
bncd16676a2016-07-20 16:23:0112781TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1112782 HttpRequestInfo unrestricted_port_request;
12783 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512784 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112785 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012786 unrestricted_port_request.traffic_annotation =
12787 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112788
[email protected]d973e99a2012-02-17 21:02:3612789 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112790 StaticSocketDataProvider first_data;
12791 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712792 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112793
12794 MockRead data_reads[] = {
12795 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12796 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612797 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112798 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112799 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712800 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112801
bncb26024382016-06-29 02:39:4512802 SSLSocketDataProvider ssl(ASYNC, OK);
12803 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12804
danakj1fd259a02016-04-16 03:17:0912805 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112806
bnc525e175a2016-06-20 12:36:4012807 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312808 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2212809 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2112810 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12811 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212812 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112813 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612814 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012815 expiration);
[email protected]3912662a32011-10-04 00:51:1112816
bnc691fda62016-08-12 00:43:1612817 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112818 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112819
bnc691fda62016-08-12 00:43:1612820 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012821 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112823 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0112824 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112825}
12826
bnc55ff9da2015-08-19 18:42:3512827// Ensure that we are not allowed to redirect traffic via an alternate protocol
Xida Chen9bfe0b62018-04-24 19:52:2112828// to an unsafe port, and that we resume the second HttpStreamFactory::Job once
12829// the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0112830TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0212831 HttpRequestInfo request;
12832 request.method = "GET";
bncce36dca22015-04-21 22:11:2312833 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012834 request.traffic_annotation =
12835 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0212836
12837 // The alternate protocol request will error out before we attempt to connect,
12838 // so only the standard HTTP request will try to connect.
12839 MockRead data_reads[] = {
12840 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12841 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612842 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0212843 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112844 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712845 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0212846
danakj1fd259a02016-04-16 03:17:0912847 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0212848
bnc525e175a2016-06-20 12:36:4012849 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0212850 session->http_server_properties();
12851 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2112852 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12853 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1212854 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112855 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612856 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0212857
bnc691fda62016-08-12 00:43:1612858 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0212859 TestCompletionCallback callback;
12860
tfarina42834112016-09-22 13:38:2012861 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112862 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0212863 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0112864 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212865
bnc691fda62016-08-12 00:43:1612866 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212867 ASSERT_TRUE(response);
12868 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0212869 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12870
12871 std::string response_data;
bnc691fda62016-08-12 00:43:1612872 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212873 EXPECT_EQ("hello world", response_data);
12874}
12875
bncd16676a2016-07-20 16:23:0112876TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5412877 HttpRequestInfo request;
12878 request.method = "GET";
bncb26024382016-06-29 02:39:4512879 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012880 request.traffic_annotation =
12881 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412882
12883 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212884 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312885 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212886 MockRead("\r\n"),
12887 MockRead("hello world"),
12888 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12889 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5412890
Ryan Sleevib8d7ea02018-05-07 20:01:0112891 StaticSocketDataProvider first_transaction(data_reads,
12892 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712893 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512894 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612895 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512896 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412897
bnc032658ba2016-09-26 18:17:1512898 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412899
Ryan Hamilton0239aac2018-05-19 00:03:1312900 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512901 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112902 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412903
Raul Tambre94493c652019-03-11 17:18:3512904 spdy::SpdySerializedFrame resp(
12905 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1312906 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412907 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112908 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412909 };
12910
Ryan Sleevib8d7ea02018-05-07 20:01:0112911 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712912 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412913
[email protected]d973e99a2012-02-17 21:02:3612914 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112915 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512916 hanging_non_alternate_protocol_socket.set_connect_data(
12917 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712918 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512919 &hanging_non_alternate_protocol_socket);
12920
[email protected]49639fa2011-12-20 23:22:4112921 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412922
danakj1fd259a02016-04-16 03:17:0912923 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812924 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912925 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412926
tfarina42834112016-09-22 13:38:2012927 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112928 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12929 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412930
12931 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212932 ASSERT_TRUE(response);
12933 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412934 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12935
12936 std::string response_data;
robpercival214763f2016-07-01 23:27:0112937 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412938 EXPECT_EQ("hello world", response_data);
12939
bnc87dcefc2017-05-25 12:47:5812940 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912941 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412942
tfarina42834112016-09-22 13:38:2012943 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12945 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412946
12947 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212948 ASSERT_TRUE(response);
12949 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212950 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312951 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212952 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412953
robpercival214763f2016-07-01 23:27:0112954 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412955 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5412956}
12957
bncd16676a2016-07-20 16:23:0112958TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5512959 HttpRequestInfo request;
12960 request.method = "GET";
bncb26024382016-06-29 02:39:4512961 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012962 request.traffic_annotation =
12963 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512964
bncb26024382016-06-29 02:39:4512965 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5512966 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212967 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312968 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212969 MockRead("\r\n"),
12970 MockRead("hello world"),
12971 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12972 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512973 };
12974
Ryan Sleevib8d7ea02018-05-07 20:01:0112975 StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
bncb26024382016-06-29 02:39:4512976 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5512977
bncb26024382016-06-29 02:39:4512978 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912979 ssl_http11.ssl_info.cert =
12980 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12981 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4512982 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
12983
12984 // Second transaction starts an alternative and a non-alternative Job.
12985 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3612986 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112987 StaticSocketDataProvider hanging_socket1;
mmenkecc2298e2015-12-07 18:20:1812988 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1812989 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
12990
Ryan Sleevib8d7ea02018-05-07 20:01:0112991 StaticSocketDataProvider hanging_socket2;
mmenkecc2298e2015-12-07 18:20:1812992 hanging_socket2.set_connect_data(never_finishing_connect);
12993 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5512994
bncb26024382016-06-29 02:39:4512995 // Third transaction starts an alternative and a non-alternative job.
12996 // The non-alternative job hangs, but the alternative one succeeds.
12997 // The second transaction, still pending, binds to this socket.
Ryan Hamilton0239aac2018-05-19 00:03:1312998 spdy::SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4512999 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1313000 spdy::SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4513001 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5513002 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113003 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5513004 };
Raul Tambre94493c652019-03-11 17:18:3513005 spdy::SpdySerializedFrame resp1(
13006 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1313007 spdy::SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
Raul Tambre94493c652019-03-11 17:18:3513008 spdy::SpdySerializedFrame resp2(
13009 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1313010 spdy::SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5513011 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113012 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
13013 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1313014 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5513015 };
13016
Ryan Sleevib8d7ea02018-05-07 20:01:0113017 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713018 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5513019
bnc032658ba2016-09-26 18:17:1513020 AddSSLSocketData();
bncb26024382016-06-29 02:39:4513021
Ryan Sleevib8d7ea02018-05-07 20:01:0113022 StaticSocketDataProvider hanging_socket3;
mmenkecc2298e2015-12-07 18:20:1813023 hanging_socket3.set_connect_data(never_finishing_connect);
13024 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5513025
danakj1fd259a02016-04-16 03:17:0913026 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4113027 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5013028 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5513029
tfarina42834112016-09-22 13:38:2013030 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113031 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13032 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513033
13034 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213035 ASSERT_TRUE(response);
13036 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513037 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13038
13039 std::string response_data;
robpercival214763f2016-07-01 23:27:0113040 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513041 EXPECT_EQ("hello world", response_data);
13042
[email protected]49639fa2011-12-20 23:22:4113043 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5013044 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2013045 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113046 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5513047
[email protected]49639fa2011-12-20 23:22:4113048 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5013049 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2013050 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113051 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5513052
robpercival214763f2016-07-01 23:27:0113053 EXPECT_THAT(callback2.WaitForResult(), IsOk());
13054 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513055
13056 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213057 ASSERT_TRUE(response);
13058 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213059 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5513060 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213061 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113062 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513063 EXPECT_EQ("hello!", response_data);
13064
13065 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5213066 ASSERT_TRUE(response);
13067 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213068 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5513069 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213070 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113071 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513072 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5513073}
13074
bncd16676a2016-07-20 16:23:0113075TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
Bence Békybcae37092018-06-12 04:18:5313076 session_deps_.host_resolver->set_synchronous_mode(true);
13077
[email protected]2d6728692011-03-12 01:39:5513078 HttpRequestInfo request;
13079 request.method = "GET";
bncb26024382016-06-29 02:39:4513080 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013081 request.traffic_annotation =
13082 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5513083
13084 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213085 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313086 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213087 MockRead("\r\n"),
13088 MockRead("hello world"),
13089 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13090 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5513091 };
13092
Ryan Sleevib8d7ea02018-05-07 20:01:0113093 StaticSocketDataProvider first_transaction(data_reads,
13094 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713095 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5513096
[email protected]8ddf8322012-02-23 18:08:0613097 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4913098 ssl.ssl_info.cert =
13099 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
13100 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0713101 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5513102
[email protected]d973e99a2012-02-17 21:02:3613103 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113104 StaticSocketDataProvider hanging_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513105 hanging_alternate_protocol_socket.set_connect_data(
13106 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713107 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513108 &hanging_alternate_protocol_socket);
13109
bncb26024382016-06-29 02:39:4513110 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
Ryan Sleevib8d7ea02018-05-07 20:01:0113111 StaticSocketDataProvider second_transaction(data_reads,
13112 base::span<MockWrite>());
mmenkecc2298e2015-12-07 18:20:1813113 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4513114 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5513115
[email protected]49639fa2011-12-20 23:22:4113116 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5513117
danakj1fd259a02016-04-16 03:17:0913118 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813119 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913120 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5513121
tfarina42834112016-09-22 13:38:2013122 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113123 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13124 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513125
13126 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213127 ASSERT_TRUE(response);
13128 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513129 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13130
13131 std::string response_data;
robpercival214763f2016-07-01 23:27:0113132 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513133 EXPECT_EQ("hello world", response_data);
13134
bnc87dcefc2017-05-25 12:47:5813135 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913136 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5513137
tfarina42834112016-09-22 13:38:2013138 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113139 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13140 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513141
13142 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213143 ASSERT_TRUE(response);
13144 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513145 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13146 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213147 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5513148
robpercival214763f2016-07-01 23:27:0113149 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513150 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5513151}
13152
bnc2e884782016-08-11 19:45:1913153// Test that proxy is resolved using the origin url,
13154// regardless of the alternative server.
13155TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
13156 // Configure proxy to bypass www.example.org, which is the origin URL.
13157 ProxyConfig proxy_config;
13158 proxy_config.proxy_rules().ParseFromString("myproxy:70");
13159 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4913160 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
13161 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1913162
13163 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1913164 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1913165 &capturing_proxy_resolver);
13166
13167 TestNetLog net_log;
13168
Bence Béky53a5aef2018-03-29 21:54:1213169 session_deps_.proxy_resolution_service =
13170 std::make_unique<ProxyResolutionService>(
13171 std::move(proxy_config_service), std::move(proxy_resolver_factory),
13172 &net_log);
bnc2e884782016-08-11 19:45:1913173
13174 session_deps_.net_log = &net_log;
13175
13176 // Configure alternative service with a hostname that is not bypassed by the
13177 // proxy.
13178 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13179 HttpServerProperties* http_server_properties =
13180 session->http_server_properties();
13181 url::SchemeHostPort server("https", "www.example.org", 443);
13182 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2113183 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1913184 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2113185 http_server_properties->SetHttp2AlternativeService(
13186 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1913187
13188 // Non-alternative job should hang.
13189 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113190 StaticSocketDataProvider hanging_alternate_protocol_socket;
bnc2e884782016-08-11 19:45:1913191 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
13192 session_deps_.socket_factory->AddSocketDataProvider(
13193 &hanging_alternate_protocol_socket);
13194
bnc032658ba2016-09-26 18:17:1513195 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1913196
13197 HttpRequestInfo request;
13198 request.method = "GET";
13199 request.url = GURL("https://www.example.org/");
13200 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1013201 request.traffic_annotation =
13202 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1913203
Ryan Hamilton0239aac2018-05-19 00:03:1313204 spdy::SpdySerializedFrame req(
bnc2e884782016-08-11 19:45:1913205 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
13206
13207 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
13208
Ryan Hamilton0239aac2018-05-19 00:03:1313209 spdy::SpdySerializedFrame resp(
13210 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13211 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc2e884782016-08-11 19:45:1913212 MockRead spdy_reads[] = {
13213 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
13214 };
13215
Ryan Sleevib8d7ea02018-05-07 20:01:0113216 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
bnc2e884782016-08-11 19:45:1913217 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
13218
13219 TestCompletionCallback callback;
13220
13221 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13222
tfarina42834112016-09-22 13:38:2013223 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1913224 EXPECT_THAT(callback.GetResult(rv), IsOk());
13225
13226 const HttpResponseInfo* response = trans.GetResponseInfo();
13227 ASSERT_TRUE(response);
13228 ASSERT_TRUE(response->headers);
13229 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13230 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213231 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1913232
13233 std::string response_data;
13234 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13235 EXPECT_EQ("hello!", response_data);
13236
13237 // Origin host bypasses proxy, no resolution should have happened.
13238 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
13239}
13240
bncd16676a2016-07-20 16:23:0113241TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1113242 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4213243 proxy_config.set_auto_detect(true);
13244 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1113245
sammc5dd160c2015-04-02 02:43:1313246 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4913247 session_deps_.proxy_resolution_service =
13248 std::make_unique<ProxyResolutionService>(
13249 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
13250 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
13251 std::make_unique<CapturingProxyResolverFactory>(
13252 &capturing_proxy_resolver),
13253 nullptr);
vishal.b62985ca92015-04-17 08:45:5113254 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0713255 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1113256
13257 HttpRequestInfo request;
13258 request.method = "GET";
bncb26024382016-06-29 02:39:4513259 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013260 request.traffic_annotation =
13261 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1113262
13263 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213264 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313265 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213266 MockRead("\r\n"),
13267 MockRead("hello world"),
13268 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13269 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1113270 };
13271
Ryan Sleevib8d7ea02018-05-07 20:01:0113272 StaticSocketDataProvider first_transaction(data_reads,
13273 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713274 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513275 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613276 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513277 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1113278
bnc032658ba2016-09-26 18:17:1513279 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1113280
Ryan Hamilton0239aac2018-05-19 00:03:1313281 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513282 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1113283 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313284 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2513285 "CONNECT www.example.org:443 HTTP/1.1\r\n"
13286 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1313287 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4113288 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1113289 };
13290
[email protected]d911f1b2010-05-05 22:39:4213291 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
13292
Raul Tambre94493c652019-03-11 17:18:3513293 spdy::SpdySerializedFrame resp(
13294 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1313295 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1113296 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113297 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
13298 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1113299 };
13300
Ryan Sleevib8d7ea02018-05-07 20:01:0113301 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713302 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1113303
[email protected]d973e99a2012-02-17 21:02:3613304 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113305 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513306 hanging_non_alternate_protocol_socket.set_connect_data(
13307 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713308 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513309 &hanging_non_alternate_protocol_socket);
13310
[email protected]49639fa2011-12-20 23:22:4113311 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1113312
danakj1fd259a02016-04-16 03:17:0913313 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813314 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913315 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113316
tfarina42834112016-09-22 13:38:2013317 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4113318 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13319 EXPECT_THAT(callback.WaitForResult(), IsOk());
13320
13321 const HttpResponseInfo* response = trans->GetResponseInfo();
13322 ASSERT_TRUE(response);
13323 ASSERT_TRUE(response->headers);
13324 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
13325 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213326 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4113327
13328 std::string response_data;
13329 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
13330 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1113331
bnc87dcefc2017-05-25 12:47:5813332 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913333 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113334
tfarina42834112016-09-22 13:38:2013335 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113336 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13337 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1113338
mmenkea2dcd3bf2016-08-16 21:49:4113339 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213340 ASSERT_TRUE(response);
13341 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213342 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313343 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213344 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1113345
robpercival214763f2016-07-01 23:27:0113346 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1113347 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4513348 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
13349 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313350 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2313351 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313352 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1113353
[email protected]029c83b62013-01-24 05:28:2013354 LoadTimingInfo load_timing_info;
13355 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
13356 TestLoadTimingNotReusedWithPac(load_timing_info,
13357 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1113358}
[email protected]631f1322010-04-30 17:59:1113359
bncd16676a2016-07-20 16:23:0113360TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4813361 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5413362 HttpRequestInfo request;
13363 request.method = "GET";
bncb26024382016-06-29 02:39:4513364 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013365 request.traffic_annotation =
13366 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5413367
13368 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213369 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313370 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213371 MockRead("\r\n"),
13372 MockRead("hello world"),
13373 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5413374 };
13375
Ryan Sleevib8d7ea02018-05-07 20:01:0113376 StaticSocketDataProvider first_transaction(data_reads,
13377 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713378 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513379 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613380 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513381 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5413382
bnc032658ba2016-09-26 18:17:1513383 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5413384
Ryan Hamilton0239aac2018-05-19 00:03:1313385 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513386 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113387 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5413388
Raul Tambre94493c652019-03-11 17:18:3513389 spdy::SpdySerializedFrame resp(
13390 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1313391 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5413392 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113393 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5413394 };
13395
Ryan Sleevib8d7ea02018-05-07 20:01:0113396 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713397 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5413398
[email protected]83039bb2011-12-09 18:43:5513399 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5413400
danakj1fd259a02016-04-16 03:17:0913401 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5413402
bnc87dcefc2017-05-25 12:47:5813403 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913404 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413405
tfarina42834112016-09-22 13:38:2013406 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113407 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13408 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413409
13410 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213411 ASSERT_TRUE(response);
13412 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5413413 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13414
13415 std::string response_data;
robpercival214763f2016-07-01 23:27:0113416 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413417 EXPECT_EQ("hello world", response_data);
13418
13419 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2513420 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013421 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1113422 PRIVACY_MODE_DISABLED,
13423 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2713424 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213425 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3813426
bnc87dcefc2017-05-25 12:47:5813427 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913428 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413429
tfarina42834112016-09-22 13:38:2013430 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113431 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13432 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413433
13434 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213435 ASSERT_TRUE(response);
13436 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213437 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313438 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213439 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5413440
robpercival214763f2016-07-01 23:27:0113441 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413442 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4213443}
13444
[email protected]044de0642010-06-17 10:42:1513445// GenerateAuthToken is a mighty big test.
13446// It tests all permutation of GenerateAuthToken behavior:
13447// - Synchronous and Asynchronous completion.
13448// - OK or error on completion.
13449// - Direct connection, non-authenticating proxy, and authenticating proxy.
13450// - HTTP or HTTPS backend (to include proxy tunneling).
13451// - Non-authenticating and authenticating backend.
13452//
[email protected]fe3b7dc2012-02-03 19:52:0913453// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1513454// problems generating an auth token for an authenticating proxy, we don't
13455// need to test all permutations of the backend server).
13456//
13457// The test proceeds by going over each of the configuration cases, and
13458// potentially running up to three rounds in each of the tests. The TestConfig
13459// specifies both the configuration for the test as well as the expectations
13460// for the results.
bncd16676a2016-07-20 16:23:0113461TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5013462 static const char kServer[] = "http://www.example.com";
13463 static const char kSecureServer[] = "https://www.example.com";
13464 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1513465
13466 enum AuthTiming {
13467 AUTH_NONE,
13468 AUTH_SYNC,
13469 AUTH_ASYNC,
13470 };
13471
13472 const MockWrite kGet(
13473 "GET / HTTP/1.1\r\n"
13474 "Host: www.example.com\r\n"
13475 "Connection: keep-alive\r\n\r\n");
13476 const MockWrite kGetProxy(
13477 "GET http://www.example.com/ HTTP/1.1\r\n"
13478 "Host: www.example.com\r\n"
13479 "Proxy-Connection: keep-alive\r\n\r\n");
13480 const MockWrite kGetAuth(
13481 "GET / HTTP/1.1\r\n"
13482 "Host: www.example.com\r\n"
13483 "Connection: keep-alive\r\n"
13484 "Authorization: auth_token\r\n\r\n");
13485 const MockWrite kGetProxyAuth(
13486 "GET http://www.example.com/ HTTP/1.1\r\n"
13487 "Host: www.example.com\r\n"
13488 "Proxy-Connection: keep-alive\r\n"
13489 "Proxy-Authorization: auth_token\r\n\r\n");
13490 const MockWrite kGetAuthThroughProxy(
13491 "GET http://www.example.com/ HTTP/1.1\r\n"
13492 "Host: www.example.com\r\n"
13493 "Proxy-Connection: keep-alive\r\n"
13494 "Authorization: auth_token\r\n\r\n");
13495 const MockWrite kGetAuthWithProxyAuth(
13496 "GET http://www.example.com/ HTTP/1.1\r\n"
13497 "Host: www.example.com\r\n"
13498 "Proxy-Connection: keep-alive\r\n"
13499 "Proxy-Authorization: auth_token\r\n"
13500 "Authorization: auth_token\r\n\r\n");
13501 const MockWrite kConnect(
13502 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713503 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513504 "Proxy-Connection: keep-alive\r\n\r\n");
13505 const MockWrite kConnectProxyAuth(
13506 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713507 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513508 "Proxy-Connection: keep-alive\r\n"
13509 "Proxy-Authorization: auth_token\r\n\r\n");
13510
13511 const MockRead kSuccess(
13512 "HTTP/1.1 200 OK\r\n"
13513 "Content-Type: text/html; charset=iso-8859-1\r\n"
13514 "Content-Length: 3\r\n\r\n"
13515 "Yes");
13516 const MockRead kFailure(
13517 "Should not be called.");
13518 const MockRead kServerChallenge(
13519 "HTTP/1.1 401 Unauthorized\r\n"
13520 "WWW-Authenticate: Mock realm=server\r\n"
13521 "Content-Type: text/html; charset=iso-8859-1\r\n"
13522 "Content-Length: 14\r\n\r\n"
13523 "Unauthorized\r\n");
13524 const MockRead kProxyChallenge(
13525 "HTTP/1.1 407 Unauthorized\r\n"
13526 "Proxy-Authenticate: Mock realm=proxy\r\n"
13527 "Proxy-Connection: close\r\n"
13528 "Content-Type: text/html; charset=iso-8859-1\r\n"
13529 "Content-Length: 14\r\n\r\n"
13530 "Unauthorized\r\n");
13531 const MockRead kProxyConnected(
13532 "HTTP/1.1 200 Connection Established\r\n\r\n");
13533
13534 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
13535 // no constructors, but the C++ compiler on Windows warns about
13536 // unspecified data in compound literals. So, moved to using constructors,
13537 // and TestRound's created with the default constructor should not be used.
13538 struct TestRound {
13539 TestRound()
Raul Tambre94493c652019-03-11 17:18:3513540 : expected_rv(ERR_UNEXPECTED),
13541 extra_write(nullptr),
13542 extra_read(nullptr) {}
Raul Tambre8335a6d2019-02-21 16:57:4313543 TestRound(const MockWrite& write_arg,
13544 const MockRead& read_arg,
[email protected]044de0642010-06-17 10:42:1513545 int expected_rv_arg)
13546 : write(write_arg),
13547 read(read_arg),
13548 expected_rv(expected_rv_arg),
Raul Tambre94493c652019-03-11 17:18:3513549 extra_write(nullptr),
13550 extra_read(nullptr) {}
[email protected]044de0642010-06-17 10:42:1513551 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
13552 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0113553 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1513554 : write(write_arg),
13555 read(read_arg),
13556 expected_rv(expected_rv_arg),
13557 extra_write(extra_write_arg),
13558 extra_read(extra_read_arg) {
13559 }
13560 MockWrite write;
13561 MockRead read;
13562 int expected_rv;
13563 const MockWrite* extra_write;
13564 const MockRead* extra_read;
13565 };
13566
13567 static const int kNoSSL = 500;
13568
13569 struct TestConfig {
asanka463ca4262016-11-16 02:34:3113570 int line_number;
thestig9d3bb0c2015-01-24 00:49:5113571 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1513572 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3113573 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5113574 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1513575 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3113576 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1513577 int num_auth_rounds;
13578 int first_ssl_round;
asankae2257db2016-10-11 22:03:1613579 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1513580 } test_configs[] = {
asankac93076192016-10-03 15:46:0213581 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113582 {__LINE__,
13583 nullptr,
asankac93076192016-10-03 15:46:0213584 AUTH_NONE,
13585 OK,
13586 kServer,
13587 AUTH_NONE,
13588 OK,
13589 1,
13590 kNoSSL,
13591 {TestRound(kGet, kSuccess, OK)}},
13592 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113593 {__LINE__,
13594 nullptr,
asankac93076192016-10-03 15:46:0213595 AUTH_NONE,
13596 OK,
13597 kServer,
13598 AUTH_SYNC,
13599 OK,
13600 2,
13601 kNoSSL,
13602 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513603 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113604 {__LINE__,
13605 nullptr,
asankac93076192016-10-03 15:46:0213606 AUTH_NONE,
13607 OK,
13608 kServer,
13609 AUTH_SYNC,
13610 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613611 3,
13612 kNoSSL,
13613 {TestRound(kGet, kServerChallenge, OK),
13614 TestRound(kGet, kServerChallenge, OK),
13615 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113616 {__LINE__,
13617 nullptr,
asankae2257db2016-10-11 22:03:1613618 AUTH_NONE,
13619 OK,
13620 kServer,
13621 AUTH_SYNC,
13622 ERR_UNSUPPORTED_AUTH_SCHEME,
13623 2,
13624 kNoSSL,
13625 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113626 {__LINE__,
13627 nullptr,
asankae2257db2016-10-11 22:03:1613628 AUTH_NONE,
13629 OK,
13630 kServer,
13631 AUTH_SYNC,
13632 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
13633 2,
13634 kNoSSL,
13635 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113636 {__LINE__,
13637 kProxy,
asankae2257db2016-10-11 22:03:1613638 AUTH_SYNC,
13639 ERR_FAILED,
13640 kServer,
13641 AUTH_NONE,
13642 OK,
13643 2,
13644 kNoSSL,
13645 {TestRound(kGetProxy, kProxyChallenge, OK),
13646 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113647 {__LINE__,
13648 kProxy,
asankae2257db2016-10-11 22:03:1613649 AUTH_ASYNC,
13650 ERR_FAILED,
13651 kServer,
13652 AUTH_NONE,
13653 OK,
13654 2,
13655 kNoSSL,
13656 {TestRound(kGetProxy, kProxyChallenge, OK),
13657 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113658 {__LINE__,
13659 nullptr,
asankae2257db2016-10-11 22:03:1613660 AUTH_NONE,
13661 OK,
13662 kServer,
13663 AUTH_SYNC,
13664 ERR_FAILED,
asankac93076192016-10-03 15:46:0213665 2,
13666 kNoSSL,
13667 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613668 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113669 {__LINE__,
13670 nullptr,
asankae2257db2016-10-11 22:03:1613671 AUTH_NONE,
13672 OK,
13673 kServer,
13674 AUTH_ASYNC,
13675 ERR_FAILED,
13676 2,
13677 kNoSSL,
13678 {TestRound(kGet, kServerChallenge, OK),
13679 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113680 {__LINE__,
13681 nullptr,
asankac93076192016-10-03 15:46:0213682 AUTH_NONE,
13683 OK,
13684 kServer,
13685 AUTH_ASYNC,
13686 OK,
13687 2,
13688 kNoSSL,
13689 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513690 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113691 {__LINE__,
13692 nullptr,
asankac93076192016-10-03 15:46:0213693 AUTH_NONE,
13694 OK,
13695 kServer,
13696 AUTH_ASYNC,
13697 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613698 3,
asankac93076192016-10-03 15:46:0213699 kNoSSL,
13700 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613701 // The second round uses a HttpAuthHandlerMock that always succeeds.
13702 TestRound(kGet, kServerChallenge, OK),
13703 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213704 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113705 {__LINE__,
13706 kProxy,
asankac93076192016-10-03 15:46:0213707 AUTH_NONE,
13708 OK,
13709 kServer,
13710 AUTH_NONE,
13711 OK,
13712 1,
13713 kNoSSL,
13714 {TestRound(kGetProxy, kSuccess, OK)}},
13715 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113716 {__LINE__,
13717 kProxy,
asankac93076192016-10-03 15:46:0213718 AUTH_NONE,
13719 OK,
13720 kServer,
13721 AUTH_SYNC,
13722 OK,
13723 2,
13724 kNoSSL,
13725 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513726 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113727 {__LINE__,
13728 kProxy,
asankac93076192016-10-03 15:46:0213729 AUTH_NONE,
13730 OK,
13731 kServer,
13732 AUTH_SYNC,
13733 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613734 3,
asankac93076192016-10-03 15:46:0213735 kNoSSL,
13736 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613737 TestRound(kGetProxy, kServerChallenge, OK),
13738 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113739 {__LINE__,
13740 kProxy,
asankac93076192016-10-03 15:46:0213741 AUTH_NONE,
13742 OK,
13743 kServer,
13744 AUTH_ASYNC,
13745 OK,
13746 2,
13747 kNoSSL,
13748 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513749 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113750 {__LINE__,
13751 kProxy,
asankac93076192016-10-03 15:46:0213752 AUTH_NONE,
13753 OK,
13754 kServer,
13755 AUTH_ASYNC,
13756 ERR_INVALID_AUTH_CREDENTIALS,
13757 2,
13758 kNoSSL,
13759 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613760 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213761 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113762 {__LINE__,
13763 kProxy,
asankac93076192016-10-03 15:46:0213764 AUTH_SYNC,
13765 OK,
13766 kServer,
13767 AUTH_NONE,
13768 OK,
13769 2,
13770 kNoSSL,
13771 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513772 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113773 {__LINE__,
13774 kProxy,
asankac93076192016-10-03 15:46:0213775 AUTH_SYNC,
13776 ERR_INVALID_AUTH_CREDENTIALS,
13777 kServer,
13778 AUTH_NONE,
13779 OK,
13780 2,
13781 kNoSSL,
13782 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613783 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113784 {__LINE__,
13785 kProxy,
asankac93076192016-10-03 15:46:0213786 AUTH_ASYNC,
13787 OK,
13788 kServer,
13789 AUTH_NONE,
13790 OK,
13791 2,
13792 kNoSSL,
13793 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513794 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113795 {__LINE__,
13796 kProxy,
asankac93076192016-10-03 15:46:0213797 AUTH_ASYNC,
13798 ERR_INVALID_AUTH_CREDENTIALS,
13799 kServer,
13800 AUTH_NONE,
13801 OK,
13802 2,
13803 kNoSSL,
13804 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613805 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113806 {__LINE__,
13807 kProxy,
13808 AUTH_ASYNC,
13809 ERR_INVALID_AUTH_CREDENTIALS,
13810 kServer,
13811 AUTH_NONE,
13812 OK,
13813 3,
13814 kNoSSL,
13815 {TestRound(kGetProxy, kProxyChallenge, OK),
13816 TestRound(kGetProxy, kProxyChallenge, OK),
13817 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213818 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113819 {__LINE__,
13820 kProxy,
asankac93076192016-10-03 15:46:0213821 AUTH_SYNC,
13822 OK,
13823 kServer,
13824 AUTH_SYNC,
13825 OK,
13826 3,
13827 kNoSSL,
13828 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513829 TestRound(kGetProxyAuth, kServerChallenge, OK),
13830 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113831 {__LINE__,
13832 kProxy,
asankac93076192016-10-03 15:46:0213833 AUTH_SYNC,
13834 OK,
13835 kServer,
13836 AUTH_SYNC,
13837 ERR_INVALID_AUTH_CREDENTIALS,
13838 3,
13839 kNoSSL,
13840 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513841 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613842 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113843 {__LINE__,
13844 kProxy,
asankac93076192016-10-03 15:46:0213845 AUTH_ASYNC,
13846 OK,
13847 kServer,
13848 AUTH_SYNC,
13849 OK,
13850 3,
13851 kNoSSL,
13852 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513853 TestRound(kGetProxyAuth, kServerChallenge, OK),
13854 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113855 {__LINE__,
13856 kProxy,
asankac93076192016-10-03 15:46:0213857 AUTH_ASYNC,
13858 OK,
13859 kServer,
13860 AUTH_SYNC,
13861 ERR_INVALID_AUTH_CREDENTIALS,
13862 3,
13863 kNoSSL,
13864 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513865 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613866 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113867 {__LINE__,
13868 kProxy,
asankac93076192016-10-03 15:46:0213869 AUTH_SYNC,
13870 OK,
13871 kServer,
13872 AUTH_ASYNC,
13873 OK,
13874 3,
13875 kNoSSL,
13876 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513877 TestRound(kGetProxyAuth, kServerChallenge, OK),
13878 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113879 {__LINE__,
13880 kProxy,
13881 AUTH_SYNC,
13882 ERR_INVALID_AUTH_CREDENTIALS,
13883 kServer,
13884 AUTH_ASYNC,
13885 OK,
13886 4,
13887 kNoSSL,
13888 {TestRound(kGetProxy, kProxyChallenge, OK),
13889 TestRound(kGetProxy, kProxyChallenge, OK),
13890 TestRound(kGetProxyAuth, kServerChallenge, OK),
13891 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
13892 {__LINE__,
13893 kProxy,
asankac93076192016-10-03 15:46:0213894 AUTH_SYNC,
13895 OK,
13896 kServer,
13897 AUTH_ASYNC,
13898 ERR_INVALID_AUTH_CREDENTIALS,
13899 3,
13900 kNoSSL,
13901 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513902 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613903 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113904 {__LINE__,
13905 kProxy,
asankac93076192016-10-03 15:46:0213906 AUTH_ASYNC,
13907 OK,
13908 kServer,
13909 AUTH_ASYNC,
13910 OK,
13911 3,
13912 kNoSSL,
13913 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513914 TestRound(kGetProxyAuth, kServerChallenge, OK),
13915 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113916 {__LINE__,
13917 kProxy,
asankac93076192016-10-03 15:46:0213918 AUTH_ASYNC,
13919 OK,
13920 kServer,
13921 AUTH_ASYNC,
13922 ERR_INVALID_AUTH_CREDENTIALS,
13923 3,
13924 kNoSSL,
13925 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513926 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613927 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113928 {__LINE__,
13929 kProxy,
13930 AUTH_ASYNC,
13931 ERR_INVALID_AUTH_CREDENTIALS,
13932 kServer,
13933 AUTH_ASYNC,
13934 ERR_INVALID_AUTH_CREDENTIALS,
13935 4,
13936 kNoSSL,
13937 {TestRound(kGetProxy, kProxyChallenge, OK),
13938 TestRound(kGetProxy, kProxyChallenge, OK),
13939 TestRound(kGetProxyAuth, kServerChallenge, OK),
13940 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213941 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113942 {__LINE__,
13943 nullptr,
asankac93076192016-10-03 15:46:0213944 AUTH_NONE,
13945 OK,
13946 kSecureServer,
13947 AUTH_NONE,
13948 OK,
13949 1,
13950 0,
13951 {TestRound(kGet, kSuccess, OK)}},
13952 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113953 {__LINE__,
13954 nullptr,
asankac93076192016-10-03 15:46:0213955 AUTH_NONE,
13956 OK,
13957 kSecureServer,
13958 AUTH_SYNC,
13959 OK,
13960 2,
13961 0,
13962 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513963 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113964 {__LINE__,
13965 nullptr,
asankac93076192016-10-03 15:46:0213966 AUTH_NONE,
13967 OK,
13968 kSecureServer,
13969 AUTH_SYNC,
13970 ERR_INVALID_AUTH_CREDENTIALS,
13971 2,
13972 0,
asankae2257db2016-10-11 22:03:1613973 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113974 {__LINE__,
13975 nullptr,
asankac93076192016-10-03 15:46:0213976 AUTH_NONE,
13977 OK,
13978 kSecureServer,
13979 AUTH_ASYNC,
13980 OK,
13981 2,
13982 0,
13983 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513984 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113985 {__LINE__,
13986 nullptr,
asankac93076192016-10-03 15:46:0213987 AUTH_NONE,
13988 OK,
13989 kSecureServer,
13990 AUTH_ASYNC,
13991 ERR_INVALID_AUTH_CREDENTIALS,
13992 2,
13993 0,
asankae2257db2016-10-11 22:03:1613994 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213995 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113996 {__LINE__,
13997 kProxy,
asankac93076192016-10-03 15:46:0213998 AUTH_NONE,
13999 OK,
14000 kSecureServer,
14001 AUTH_NONE,
14002 OK,
14003 1,
14004 0,
14005 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
14006 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3114007 {__LINE__,
14008 kProxy,
asankac93076192016-10-03 15:46:0214009 AUTH_NONE,
14010 OK,
14011 kSecureServer,
14012 AUTH_SYNC,
14013 OK,
14014 2,
14015 0,
14016 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514017 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114018 {__LINE__,
14019 kProxy,
asankac93076192016-10-03 15:46:0214020 AUTH_NONE,
14021 OK,
14022 kSecureServer,
14023 AUTH_SYNC,
14024 ERR_INVALID_AUTH_CREDENTIALS,
14025 2,
14026 0,
14027 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1614028 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114029 {__LINE__,
14030 kProxy,
asankac93076192016-10-03 15:46:0214031 AUTH_NONE,
14032 OK,
14033 kSecureServer,
14034 AUTH_ASYNC,
14035 OK,
14036 2,
14037 0,
14038 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514039 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114040 {__LINE__,
14041 kProxy,
asankac93076192016-10-03 15:46:0214042 AUTH_NONE,
14043 OK,
14044 kSecureServer,
14045 AUTH_ASYNC,
14046 ERR_INVALID_AUTH_CREDENTIALS,
14047 2,
14048 0,
14049 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1614050 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0214051 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3114052 {__LINE__,
14053 kProxy,
asankac93076192016-10-03 15:46:0214054 AUTH_SYNC,
14055 OK,
14056 kSecureServer,
14057 AUTH_NONE,
14058 OK,
14059 2,
14060 1,
14061 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1514062 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114063 {__LINE__,
14064 kProxy,
asankac93076192016-10-03 15:46:0214065 AUTH_SYNC,
14066 ERR_INVALID_AUTH_CREDENTIALS,
14067 kSecureServer,
14068 AUTH_NONE,
14069 OK,
14070 2,
14071 kNoSSL,
14072 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1614073 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114074 {__LINE__,
14075 kProxy,
asankae2257db2016-10-11 22:03:1614076 AUTH_SYNC,
14077 ERR_UNSUPPORTED_AUTH_SCHEME,
14078 kSecureServer,
14079 AUTH_NONE,
14080 OK,
14081 2,
14082 kNoSSL,
14083 {TestRound(kConnect, kProxyChallenge, OK),
14084 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114085 {__LINE__,
14086 kProxy,
asankae2257db2016-10-11 22:03:1614087 AUTH_SYNC,
14088 ERR_UNEXPECTED,
14089 kSecureServer,
14090 AUTH_NONE,
14091 OK,
14092 2,
14093 kNoSSL,
14094 {TestRound(kConnect, kProxyChallenge, OK),
14095 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3114096 {__LINE__,
14097 kProxy,
asankac93076192016-10-03 15:46:0214098 AUTH_ASYNC,
14099 OK,
14100 kSecureServer,
14101 AUTH_NONE,
14102 OK,
14103 2,
14104 1,
14105 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1514106 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114107 {__LINE__,
14108 kProxy,
asankac93076192016-10-03 15:46:0214109 AUTH_ASYNC,
14110 ERR_INVALID_AUTH_CREDENTIALS,
14111 kSecureServer,
14112 AUTH_NONE,
14113 OK,
14114 2,
14115 kNoSSL,
14116 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1614117 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0214118 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3114119 {__LINE__,
14120 kProxy,
asankac93076192016-10-03 15:46:0214121 AUTH_SYNC,
14122 OK,
14123 kSecureServer,
14124 AUTH_SYNC,
14125 OK,
14126 3,
14127 1,
14128 {TestRound(kConnect, kProxyChallenge, OK),
14129 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14130 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514131 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114132 {__LINE__,
14133 kProxy,
asankac93076192016-10-03 15:46:0214134 AUTH_SYNC,
14135 OK,
14136 kSecureServer,
14137 AUTH_SYNC,
14138 ERR_INVALID_AUTH_CREDENTIALS,
14139 3,
14140 1,
14141 {TestRound(kConnect, kProxyChallenge, OK),
14142 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14143 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614144 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114145 {__LINE__,
14146 kProxy,
asankac93076192016-10-03 15:46:0214147 AUTH_ASYNC,
14148 OK,
14149 kSecureServer,
14150 AUTH_SYNC,
14151 OK,
14152 3,
14153 1,
14154 {TestRound(kConnect, kProxyChallenge, OK),
14155 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14156 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514157 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114158 {__LINE__,
14159 kProxy,
asankac93076192016-10-03 15:46:0214160 AUTH_ASYNC,
14161 OK,
14162 kSecureServer,
14163 AUTH_SYNC,
14164 ERR_INVALID_AUTH_CREDENTIALS,
14165 3,
14166 1,
14167 {TestRound(kConnect, kProxyChallenge, OK),
14168 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14169 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614170 TestRound(kGet, 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_ASYNC,
14177 OK,
14178 3,
14179 1,
14180 {TestRound(kConnect, kProxyChallenge, OK),
14181 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14182 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514183 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114184 {__LINE__,
14185 kProxy,
asankac93076192016-10-03 15:46:0214186 AUTH_SYNC,
14187 OK,
14188 kSecureServer,
14189 AUTH_ASYNC,
14190 ERR_INVALID_AUTH_CREDENTIALS,
14191 3,
14192 1,
14193 {TestRound(kConnect, kProxyChallenge, OK),
14194 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14195 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614196 TestRound(kGet, 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_ASYNC,
14203 OK,
14204 3,
14205 1,
14206 {TestRound(kConnect, kProxyChallenge, OK),
14207 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14208 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514209 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114210 {__LINE__,
14211 kProxy,
asankac93076192016-10-03 15:46:0214212 AUTH_ASYNC,
14213 OK,
14214 kSecureServer,
14215 AUTH_ASYNC,
14216 ERR_INVALID_AUTH_CREDENTIALS,
14217 3,
14218 1,
14219 {TestRound(kConnect, kProxyChallenge, OK),
14220 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14221 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614222 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114223 {__LINE__,
14224 kProxy,
14225 AUTH_ASYNC,
14226 ERR_INVALID_AUTH_CREDENTIALS,
14227 kSecureServer,
14228 AUTH_ASYNC,
14229 ERR_INVALID_AUTH_CREDENTIALS,
14230 4,
14231 2,
14232 {TestRound(kConnect, kProxyChallenge, OK),
14233 TestRound(kConnect, kProxyChallenge, OK),
14234 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14235 &kServerChallenge),
14236 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1514237 };
14238
asanka463ca4262016-11-16 02:34:3114239 for (const auto& test_config : test_configs) {
14240 SCOPED_TRACE(::testing::Message() << "Test config at "
14241 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0814242 HttpAuthHandlerMock::Factory* auth_factory(
14243 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714244 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4914245 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2614246
14247 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1514248 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3114249 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0814250 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14251 std::string auth_challenge = "Mock realm=proxy";
14252 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2414253 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14254 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0814255 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2014256 empty_ssl_info, origin,
14257 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814258 auth_handler->SetGenerateExpectation(
14259 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114260 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0814261 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
14262 }
[email protected]044de0642010-06-17 10:42:1514263 }
14264 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0014265 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1514266 std::string auth_challenge = "Mock realm=server";
14267 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2414268 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14269 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1514270 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014271 empty_ssl_info, origin,
14272 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514273 auth_handler->SetGenerateExpectation(
14274 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114275 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0814276 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1614277
14278 // The second handler always succeeds. It should only be used where there
14279 // are multiple auth sessions for server auth in the same network
14280 // transaction using the same auth scheme.
14281 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1914282 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1614283 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
14284 empty_ssl_info, origin,
14285 NetLogWithSource());
14286 second_handler->SetGenerateExpectation(true, OK);
14287 auth_factory->AddMockHandler(second_handler.release(),
14288 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1514289 }
14290 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5914291 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914292 ProxyResolutionService::CreateFixed(test_config.proxy_url,
14293 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514294 } else {
Bence Béky53a5aef2018-03-29 21:54:1214295 session_deps_.proxy_resolution_service =
14296 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1514297 }
14298
14299 HttpRequestInfo request;
14300 request.method = "GET";
14301 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e62018-02-07 07:41:1014302 request.traffic_annotation =
14303 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514304
danakj1fd259a02016-04-16 03:17:0914305 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1514306
rchcb68dc62015-05-21 04:45:3614307 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
14308
14309 std::vector<std::vector<MockRead>> mock_reads(1);
14310 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1514311 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214312 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1514313 const TestRound& read_write_round = test_config.rounds[round];
14314
14315 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3614316 mock_reads.back().push_back(read_write_round.read);
14317 mock_writes.back().push_back(read_write_round.write);
14318
14319 // kProxyChallenge uses Proxy-Connection: close which means that the
14320 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5414321 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3614322 mock_reads.push_back(std::vector<MockRead>());
14323 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1514324 }
14325
rchcb68dc62015-05-21 04:45:3614326 if (read_write_round.extra_read) {
14327 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1514328 }
rchcb68dc62015-05-21 04:45:3614329 if (read_write_round.extra_write) {
14330 mock_writes.back().push_back(*read_write_round.extra_write);
14331 }
[email protected]044de0642010-06-17 10:42:1514332
14333 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1514334 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0714335 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1514336 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3614337 }
[email protected]044de0642010-06-17 10:42:1514338
danakj1fd259a02016-04-16 03:17:0914339 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3614340 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1914341 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:0114342 mock_reads[i], mock_writes[i]));
rchcb68dc62015-05-21 04:45:3614343 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3214344 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3614345 }
14346
mmenkecc2298e2015-12-07 18:20:1814347 // Transaction must be created after DataProviders, so it's destroyed before
14348 // they are as well.
14349 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14350
rchcb68dc62015-05-21 04:45:3614351 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214352 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3614353 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1514354 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4114355 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1514356 int rv;
14357 if (round == 0) {
tfarina42834112016-09-22 13:38:2014358 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514359 } else {
[email protected]49639fa2011-12-20 23:22:4114360 rv = trans.RestartWithAuth(
14361 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1514362 }
14363 if (rv == ERR_IO_PENDING)
14364 rv = callback.WaitForResult();
14365
14366 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1614367 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5014368 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5514369 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1514370 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
14371 continue;
14372 }
14373 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5214374 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1514375 } else {
wezca1070932016-05-26 20:30:5214376 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1614377 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1514378 }
14379 }
[email protected]e5ae96a2010-04-14 20:12:4514380 }
14381}
14382
bncd16676a2016-07-20 16:23:0114383TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1414384 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1414385 HttpAuthHandlerMock::Factory* auth_factory(
14386 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714387 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1214388 session_deps_.proxy_resolution_service =
14389 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0714390 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
[email protected]c871bce92010-07-15 21:51:1414391
14392 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14393 auth_handler->set_connection_based(true);
14394 std::string auth_challenge = "Mock realm=server";
14395 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2414396 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14397 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4914398 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1414399 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014400 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814401 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1414402
[email protected]c871bce92010-07-15 21:51:1414403 int rv = OK;
Raul Tambre94493c652019-03-11 17:18:3514404 const HttpResponseInfo* response = nullptr;
[email protected]c871bce92010-07-15 21:51:1414405 HttpRequestInfo request;
14406 request.method = "GET";
14407 request.url = origin;
Ramin Halavatib5e433e62018-02-07 07:41:1014408 request.traffic_annotation =
14409 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714410
danakj1fd259a02016-04-16 03:17:0914411 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1014412
14413 // Use a TCP Socket Pool with only one connection per group. This is used
14414 // to validate that the TCP socket is not released to the pool between
14415 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4214416 HttpNetworkSessionPeer session_peer(session.get());
Matt Menked6fd2a52019-03-20 06:14:3614417 CommonConnectJobParams common_connect_job_params(
14418 session->CreateCommonConnectJobParams());
[email protected]ab739042011-04-07 15:22:2814419 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
Tarun Bansala7635092019-02-20 10:00:5914420 50, // Max sockets for pool
14421 1, // Max sockets per group
14422 base::TimeDelta::FromSeconds(10), // unused_idle_socket_timeout
Matt Menked6fd2a52019-03-20 06:14:3614423 &common_connect_job_params, session_deps_.ssl_config_service.get());
Jeremy Roman0579ed62017-08-29 15:56:1914424 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4014425 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
14426 base::WrapUnique(transport_pool));
dchengc7eeda422015-12-26 03:56:4814427 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1014428
bnc691fda62016-08-12 00:43:1614429 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114430 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1414431
14432 const MockWrite kGet(
14433 "GET / HTTP/1.1\r\n"
14434 "Host: www.example.com\r\n"
14435 "Connection: keep-alive\r\n\r\n");
14436 const MockWrite kGetAuth(
14437 "GET / HTTP/1.1\r\n"
14438 "Host: www.example.com\r\n"
14439 "Connection: keep-alive\r\n"
14440 "Authorization: auth_token\r\n\r\n");
14441
14442 const MockRead kServerChallenge(
14443 "HTTP/1.1 401 Unauthorized\r\n"
14444 "WWW-Authenticate: Mock realm=server\r\n"
14445 "Content-Type: text/html; charset=iso-8859-1\r\n"
14446 "Content-Length: 14\r\n\r\n"
14447 "Unauthorized\r\n");
14448 const MockRead kSuccess(
14449 "HTTP/1.1 200 OK\r\n"
14450 "Content-Type: text/html; charset=iso-8859-1\r\n"
14451 "Content-Length: 3\r\n\r\n"
14452 "Yes");
14453
14454 MockWrite writes[] = {
14455 // First round
14456 kGet,
14457 // Second round
14458 kGetAuth,
14459 // Third round
14460 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3014461 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1014462 kGetAuth,
14463 // Competing request
14464 kGet,
[email protected]c871bce92010-07-15 21:51:1414465 };
14466 MockRead reads[] = {
14467 // First round
14468 kServerChallenge,
14469 // Second round
14470 kServerChallenge,
14471 // Third round
[email protected]eca50e122010-09-11 14:03:3014472 kServerChallenge,
14473 // Fourth round
[email protected]c871bce92010-07-15 21:51:1414474 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1014475 // Competing response
14476 kSuccess,
[email protected]c871bce92010-07-15 21:51:1414477 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114478 StaticSocketDataProvider data_provider(reads, writes);
[email protected]bb88e1d32013-05-03 23:11:0714479 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1414480
Matt Menkef6edce752019-03-19 17:21:5614481 const ClientSocketPool::GroupId kSocketGroup(
14482 HostPortPair("www.example.com", 80), ClientSocketPool::SocketType::kHttp,
14483 false /* privacy_mode */);
[email protected]7ef4cbbb2011-02-06 11:19:1014484
14485 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1414486 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2014487 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1414488 if (rv == ERR_IO_PENDING)
14489 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114490 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614491 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214492 ASSERT_TRUE(response);
14493 EXPECT_TRUE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314494 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114495 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14496 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414497
[email protected]7ef4cbbb2011-02-06 11:19:1014498 // In between rounds, another request comes in for the same domain.
14499 // It should not be able to grab the TCP socket that trans has already
14500 // claimed.
bnc691fda62016-08-12 00:43:1614501 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114502 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2014503 rv = trans_compete.Start(&request, callback_compete.callback(),
14504 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114505 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1014506 // callback_compete.WaitForResult at this point would stall forever,
14507 // since the HttpNetworkTransaction does not release the request back to
14508 // the pool until after authentication completes.
14509
14510 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1414511 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614512 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414513 if (rv == ERR_IO_PENDING)
14514 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114515 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614516 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214517 ASSERT_TRUE(response);
14518 EXPECT_FALSE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314519 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114520 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14521 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414522
[email protected]7ef4cbbb2011-02-06 11:19:1014523 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1414524 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614525 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414526 if (rv == ERR_IO_PENDING)
14527 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114528 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614529 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214530 ASSERT_TRUE(response);
14531 EXPECT_FALSE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314532 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114533 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14534 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3014535
[email protected]7ef4cbbb2011-02-06 11:19:1014536 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3014537 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614538 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3014539 if (rv == ERR_IO_PENDING)
14540 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114541 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614542 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214543 ASSERT_TRUE(response);
14544 EXPECT_FALSE(response->auth_challenge);
Raul Tambre8335a6d2019-02-21 16:57:4314545 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014546
asanka463ca4262016-11-16 02:34:3114547 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
14548 // auth handler should transition to a DONE state in concert with the remote
14549 // server. But that's not something we can test here with a mock handler.
14550 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
14551 auth_handler->state());
14552
[email protected]7ef4cbbb2011-02-06 11:19:1014553 // Read the body since the fourth round was successful. This will also
14554 // release the socket back to the pool.
Victor Costan9c7302b2018-08-27 16:39:4414555 scoped_refptr<IOBufferWithSize> io_buf =
14556 base::MakeRefCounted<IOBufferWithSize>(50);
bnc691fda62016-08-12 00:43:1614557 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014558 if (rv == ERR_IO_PENDING)
14559 rv = callback.WaitForResult();
14560 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614561 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014562 EXPECT_EQ(0, rv);
14563 // There are still 0 idle sockets, since the trans_compete transaction
14564 // will be handed it immediately after trans releases it to the group.
Raul Tambre8335a6d2019-02-21 16:57:4314565 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014566
14567 // The competing request can now finish. Wait for the headers and then
14568 // read the body.
14569 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0114570 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614571 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014572 if (rv == ERR_IO_PENDING)
14573 rv = callback.WaitForResult();
14574 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614575 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014576 EXPECT_EQ(0, rv);
14577
14578 // Finally, the socket is released to the group.
Raul Tambre8335a6d2019-02-21 16:57:4314579 EXPECT_EQ(1u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1414580}
14581
[email protected]65041fa2010-05-21 06:56:5314582// This tests the case that a request is issued via http instead of spdy after
14583// npn is negotiated.
bncd16676a2016-07-20 16:23:0114584TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5314585 HttpRequestInfo request;
14586 request.method = "GET";
bncce36dca22015-04-21 22:11:2314587 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014588 request.traffic_annotation =
14589 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5314590
14591 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314592 MockWrite(
14593 "GET / HTTP/1.1\r\n"
14594 "Host: www.example.org\r\n"
14595 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5314596 };
14597
14598 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5214599 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4314600 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5214601 MockRead("\r\n"),
14602 MockRead("hello world"),
14603 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5314604 };
14605
[email protected]8ddf8322012-02-23 18:08:0614606 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614607 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5314608
[email protected]bb88e1d32013-05-03 23:11:0714609 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5314610
Ryan Sleevib8d7ea02018-05-07 20:01:0114611 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714612 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5314613
[email protected]49639fa2011-12-20 23:22:4114614 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5314615
danakj1fd259a02016-04-16 03:17:0914616 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614617 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5314618
tfarina42834112016-09-22 13:38:2014619 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5314620
robpercival214763f2016-07-01 23:27:0114621 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14622 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5314623
bnc691fda62016-08-12 00:43:1614624 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214625 ASSERT_TRUE(response);
14626 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5314627 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14628
14629 std::string response_data;
bnc691fda62016-08-12 00:43:1614630 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5314631 EXPECT_EQ("hello world", response_data);
14632
14633 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214634 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5314635}
[email protected]26ef6582010-06-24 02:30:4714636
bnc55ff9da2015-08-19 18:42:3514637// Simulate the SSL handshake completing with an NPN negotiation followed by an
14638// immediate server closing of the socket.
14639// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0114640TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4714641 HttpRequestInfo request;
14642 request.method = "GET";
bncce36dca22015-04-21 22:11:2314643 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014644 request.traffic_annotation =
14645 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4714646
[email protected]8ddf8322012-02-23 18:08:0614647 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614648 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714649 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4714650
Ryan Hamilton0239aac2018-05-19 00:03:1314651 spdy::SpdySerializedFrame req(
14652 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114653 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4714654
14655 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614656 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4714657 };
14658
Ryan Sleevib8d7ea02018-05-07 20:01:0114659 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714660 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4714661
[email protected]49639fa2011-12-20 23:22:4114662 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4714663
danakj1fd259a02016-04-16 03:17:0914664 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614665 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4714666
tfarina42834112016-09-22 13:38:2014667 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114668 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14669 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4714670}
[email protected]65d34382010-07-01 18:12:2614671
[email protected]795cbf82013-07-22 09:37:2714672// A subclass of HttpAuthHandlerMock that records the request URL when
14673// it gets it. This is needed since the auth handler may get destroyed
14674// before we get a chance to query it.
14675class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
14676 public:
14677 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
14678
Chris Watkins7a41d3552017-12-01 02:13:2714679 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2714680
14681 protected:
dchengb03027d2014-10-21 12:00:2014682 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
14683 const HttpRequestInfo* request,
Bence Béky7236fb72018-08-01 14:35:0914684 CompletionOnceCallback callback,
dchengb03027d2014-10-21 12:00:2014685 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2714686 *url_ = request->url;
14687 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
Bence Béky7236fb72018-08-01 14:35:0914688 credentials, request, std::move(callback), auth_token);
[email protected]795cbf82013-07-22 09:37:2714689 }
14690
14691 private:
14692 GURL* url_;
14693};
14694
[email protected]8e6441ca2010-08-19 05:56:3814695// Test that if we cancel the transaction as the connection is completing, that
14696// everything tears down correctly.
bncd16676a2016-07-20 16:23:0114697TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3814698 // Setup everything about the connection to complete synchronously, so that
14699 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
14700 // for is the callback from the HttpStreamRequest.
14701 // Then cancel the transaction.
14702 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3614703 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3814704 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614705 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
14706 MockRead(SYNCHRONOUS, "hello world"),
14707 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3814708 };
14709
[email protected]8e6441ca2010-08-19 05:56:3814710 HttpRequestInfo request;
14711 request.method = "GET";
bncce36dca22015-04-21 22:11:2314712 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014713 request.traffic_annotation =
14714 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3814715
danakj1fd259a02016-04-16 03:17:0914716 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5814717 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1914718 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2714719
Ryan Sleevib8d7ea02018-05-07 20:01:0114720 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]8e6441ca2010-08-19 05:56:3814721 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0714722 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3814723
[email protected]49639fa2011-12-20 23:22:4114724 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3814725
vishal.b62985ca92015-04-17 08:45:5114726 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4114727 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114728 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3814729 trans.reset(); // Cancel the transaction here.
14730
fdoray92e35a72016-06-10 15:54:5514731 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3014732}
14733
[email protected]ecab6e052014-05-16 14:58:1214734// Test that if a transaction is cancelled after receiving the headers, the
14735// stream is drained properly and added back to the socket pool. The main
14736// purpose of this test is to make sure that an HttpStreamParser can be read
14737// from after the HttpNetworkTransaction and the objects it owns have been
14738// deleted.
14739// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0114740TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1214741 MockRead data_reads[] = {
14742 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
14743 MockRead(ASYNC, "Content-Length: 2\r\n"),
14744 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
14745 MockRead(ASYNC, "1"),
14746 // 2 async reads are necessary to trigger a ReadResponseBody call after the
14747 // HttpNetworkTransaction has been deleted.
14748 MockRead(ASYNC, "2"),
14749 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
14750 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114751 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]ecab6e052014-05-16 14:58:1214752 session_deps_.socket_factory->AddSocketDataProvider(&data);
14753
danakj1fd259a02016-04-16 03:17:0914754 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1214755
14756 {
14757 HttpRequestInfo request;
14758 request.method = "GET";
bncce36dca22015-04-21 22:11:2314759 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014760 request.traffic_annotation =
14761 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1214762
dcheng48459ac22014-08-26 00:46:4114763 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1214764 TestCompletionCallback callback;
14765
tfarina42834112016-09-22 13:38:2014766 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114767 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1214768 callback.WaitForResult();
14769
14770 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214771 ASSERT_TRUE(response);
14772 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1214773 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14774
14775 // The transaction and HttpRequestInfo are deleted.
14776 }
14777
14778 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5514779 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1214780
14781 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4114782 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1214783}
14784
[email protected]76a505b2010-08-25 06:23:0014785// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0114786TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914787 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914788 ProxyResolutionService::CreateFixedFromPacResult(
14789 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114790 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714791 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914792 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014793
[email protected]76a505b2010-08-25 06:23:0014794 HttpRequestInfo request;
14795 request.method = "GET";
bncce36dca22015-04-21 22:11:2314796 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014797 request.traffic_annotation =
14798 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014799
14800 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2314801 MockWrite(
14802 "GET http://www.example.org/ HTTP/1.1\r\n"
14803 "Host: www.example.org\r\n"
14804 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014805 };
14806
14807 MockRead data_reads1[] = {
14808 MockRead("HTTP/1.1 200 OK\r\n"),
14809 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14810 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614811 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014812 };
14813
Ryan Sleevib8d7ea02018-05-07 20:01:0114814 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714815 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0014816
[email protected]49639fa2011-12-20 23:22:4114817 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014818
bnc691fda62016-08-12 00:43:1614819 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914820 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614821 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914822 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14823 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014824
bnc691fda62016-08-12 00:43:1614825 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114826 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014827
14828 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114829 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0014830
bnc691fda62016-08-12 00:43:1614831 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214832 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014833
14834 EXPECT_TRUE(response->headers->IsKeepAlive());
14835 EXPECT_EQ(200, response->headers->response_code());
14836 EXPECT_EQ(100, response->headers->GetContentLength());
14837 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714838 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14839 HostPortPair::FromString("myproxy:70")),
14840 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914841 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14842 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14843 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0014844 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2014845
14846 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614847 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014848 TestLoadTimingNotReusedWithPac(load_timing_info,
14849 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0014850}
14851
14852// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0114853TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914854 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914855 ProxyResolutionService::CreateFixedFromPacResult(
14856 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114857 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714858 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914859 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014860
[email protected]76a505b2010-08-25 06:23:0014861 HttpRequestInfo request;
14862 request.method = "GET";
bncce36dca22015-04-21 22:11:2314863 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014864 request.traffic_annotation =
14865 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014866
14867 // Since we have proxy, should try to establish tunnel.
14868 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714869 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14870 "Host: www.example.org:443\r\n"
14871 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014872
rsleevidb16bb02015-11-12 23:47:1714873 MockWrite("GET / HTTP/1.1\r\n"
14874 "Host: www.example.org\r\n"
14875 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014876 };
14877
14878 MockRead data_reads1[] = {
14879 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14880
14881 MockRead("HTTP/1.1 200 OK\r\n"),
14882 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14883 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614884 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014885 };
14886
Ryan Sleevib8d7ea02018-05-07 20:01:0114887 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714888 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614889 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714890 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014891
[email protected]49639fa2011-12-20 23:22:4114892 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014893
bnc691fda62016-08-12 00:43:1614894 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914895 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614896 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914897 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14898 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014899
bnc691fda62016-08-12 00:43:1614900 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114901 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014902
14903 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114904 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4614905 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014906 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014907 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014908 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14909 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014910 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014911 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014912 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14913 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014914
bnc691fda62016-08-12 00:43:1614915 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214916 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014917
14918 EXPECT_TRUE(response->headers->IsKeepAlive());
14919 EXPECT_EQ(200, response->headers->response_code());
14920 EXPECT_EQ(100, response->headers->GetContentLength());
14921 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14922 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714923 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14924 HostPortPair::FromString("myproxy:70")),
14925 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914926 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14927 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14928 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2014929
14930 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614931 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014932 TestLoadTimingNotReusedWithPac(load_timing_info,
14933 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0014934}
14935
rsleevidb16bb02015-11-12 23:47:1714936// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
14937// literal host.
bncd16676a2016-07-20 16:23:0114938TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5914939 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914940 ProxyResolutionService::CreateFixedFromPacResult(
14941 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714942 BoundTestNetLog log;
14943 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914944 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1714945
14946 HttpRequestInfo request;
14947 request.method = "GET";
Eric Romanda790f92018-11-07 19:17:1514948 request.url = GURL("https://[::2]:443/");
Ramin Halavatib5e433e62018-02-07 07:41:1014949 request.traffic_annotation =
14950 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714951
14952 // Since we have proxy, should try to establish tunnel.
14953 MockWrite data_writes1[] = {
Eric Romanda790f92018-11-07 19:17:1514954 MockWrite("CONNECT [::2]:443 HTTP/1.1\r\n"
14955 "Host: [::2]:443\r\n"
rsleevidb16bb02015-11-12 23:47:1714956 "Proxy-Connection: keep-alive\r\n\r\n"),
14957
14958 MockWrite("GET / HTTP/1.1\r\n"
Eric Romanda790f92018-11-07 19:17:1514959 "Host: [::2]\r\n"
rsleevidb16bb02015-11-12 23:47:1714960 "Connection: keep-alive\r\n\r\n"),
14961 };
14962
14963 MockRead data_reads1[] = {
14964 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14965
14966 MockRead("HTTP/1.1 200 OK\r\n"),
14967 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14968 MockRead("Content-Length: 100\r\n\r\n"),
14969 MockRead(SYNCHRONOUS, OK),
14970 };
14971
Ryan Sleevib8d7ea02018-05-07 20:01:0114972 StaticSocketDataProvider data1(data_reads1, data_writes1);
rsleevidb16bb02015-11-12 23:47:1714973 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14974 SSLSocketDataProvider ssl(ASYNC, OK);
14975 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14976
14977 TestCompletionCallback callback1;
14978
bnc691fda62016-08-12 00:43:1614979 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714980
bnc691fda62016-08-12 00:43:1614981 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114982 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714983
14984 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114985 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714986 TestNetLogEntry::List entries;
14987 log.GetEntries(&entries);
14988 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014989 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14990 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714991 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014992 entries, pos,
14993 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14994 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714995
bnc691fda62016-08-12 00:43:1614996 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214997 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714998
14999 EXPECT_TRUE(response->headers->IsKeepAlive());
15000 EXPECT_EQ(200, response->headers->response_code());
15001 EXPECT_EQ(100, response->headers->GetContentLength());
15002 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
15003 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4715004 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
15005 HostPortPair::FromString("myproxy:70")),
15006 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1715007
15008 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1615009 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1715010 TestLoadTimingNotReusedWithPac(load_timing_info,
15011 CONNECT_TIMING_HAS_SSL_TIMES);
15012}
15013
[email protected]76a505b2010-08-25 06:23:0015014// Test a basic HTTPS GET request through a proxy, but the server hangs up
15015// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0115016TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4915017 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
15018 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115019 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715020 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0915021 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0015022
[email protected]76a505b2010-08-25 06:23:0015023 HttpRequestInfo request;
15024 request.method = "GET";
bncce36dca22015-04-21 22:11:2315025 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015026 request.traffic_annotation =
15027 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0015028
15029 // Since we have proxy, should try to establish tunnel.
15030 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1715031 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15032 "Host: www.example.org:443\r\n"
15033 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0015034
rsleevidb16bb02015-11-12 23:47:1715035 MockWrite("GET / HTTP/1.1\r\n"
15036 "Host: www.example.org\r\n"
15037 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0015038 };
15039
15040 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0015041 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0615042 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0015043 };
15044
Ryan Sleevib8d7ea02018-05-07 20:01:0115045 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0715046 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0615047 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0715048 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0015049
[email protected]49639fa2011-12-20 23:22:4115050 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0015051
bnc691fda62016-08-12 00:43:1615052 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5015053
bnc691fda62016-08-12 00:43:1615054 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0115055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0015056
15057 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0115058 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4615059 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4015060 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0015061 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0015062 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
15063 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0015064 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4015065 entries, pos,
mikecirone8b85c432016-09-08 19:11:0015066 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
15067 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0015068}
15069
[email protected]749eefa82010-09-13 22:14:0315070// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0115071TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
Ryan Hamilton0239aac2018-05-19 00:03:1315072 spdy::SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4915073 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115074 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0315075
Raul Tambre94493c652019-03-11 17:18:3515076 spdy::SpdySerializedFrame resp(
15077 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315078 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0315079 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115080 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0315081 };
15082
Ryan Sleevib8d7ea02018-05-07 20:01:0115083 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715084 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0315085
[email protected]8ddf8322012-02-23 18:08:0615086 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615087 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715088 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0315089
danakj1fd259a02016-04-16 03:17:0915090 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0315091
15092 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2315093 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4015094 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1115095 PRIVACY_MODE_DISABLED,
15096 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2715097 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5215098 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0315099
15100 HttpRequestInfo request;
15101 request.method = "GET";
bncce36dca22015-04-21 22:11:2315102 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015103 request.traffic_annotation =
15104 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0315105
bnc691fda62016-08-12 00:43:1615106 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0315107
[email protected]41d64e82013-07-03 22:44:2615108 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015109 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15111 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0315112}
15113
[email protected]73b8dd222010-11-11 19:55:2415114// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1615115// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0215116void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0715117 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2915118 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715119 request_info.url = GURL("https://www.example.com/");
15120 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915121 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015122 request_info.traffic_annotation =
15123 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715124
[email protected]8ddf8322012-02-23 18:08:0615125 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2915126 MockWrite data_writes[] = {
15127 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2415128 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115129 StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
[email protected]bb88e1d32013-05-03 23:11:0715130 session_deps_.socket_factory->AddSocketDataProvider(&data);
15131 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2415132
danakj1fd259a02016-04-16 03:17:0915133 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615134 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2415135
[email protected]49639fa2011-12-20 23:22:4115136 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015137 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2915138 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2415139 rv = callback.WaitForResult();
15140 ASSERT_EQ(error, rv);
15141}
15142
bncd16676a2016-07-20 16:23:0115143TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2415144 // Just check a grab bag of cert errors.
15145 static const int kErrors[] = {
15146 ERR_CERT_COMMON_NAME_INVALID,
15147 ERR_CERT_AUTHORITY_INVALID,
15148 ERR_CERT_DATE_INVALID,
15149 };
Avi Drissman4365a4782018-12-28 19:26:2415150 for (size_t i = 0; i < base::size(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0615151 CheckErrorIsPassedBack(kErrors[i], ASYNC);
15152 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2415153 }
15154}
15155
[email protected]bd0b6772011-01-11 19:59:3015156// Ensure that a client certificate is removed from the SSL client auth
15157// cache when:
15158// 1) No proxy is involved.
15159// 2) TLS False Start is disabled.
15160// 3) The initial TLS handshake requests a client certificate.
15161// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115162TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915163 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715164 request_info.url = GURL("https://www.example.com/");
15165 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915166 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015167 request_info.traffic_annotation =
15168 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715169
[email protected]bd0b6772011-01-11 19:59:3015170 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115171 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015172
15173 // [ssl_]data1 contains the data for the first SSL handshake. When a
15174 // CertificateRequest is received for the first time, the handshake will
15175 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2915176 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015177 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715178 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115179 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715180 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015181
15182 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
15183 // False Start is not being used, the result of the SSL handshake will be
15184 // returned as part of the SSLClientSocket::Connect() call. This test
15185 // matches the result of a server sending a handshake_failure alert,
15186 // rather than a Finished message, because it requires a client
15187 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2915188 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3015189 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715190 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115191 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715192 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015193
15194 // [ssl_]data3 contains the data for the third SSL handshake. When a
15195 // connection to a server fails during an SSL handshake,
Steven Valdez0ef94d02018-11-19 23:28:1315196 // HttpNetworkTransaction will attempt to fallback to TLSv1.2 if the previous
15197 // connection was attempted with TLSv1.3. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3015198 // of the HttpNetworkTransaction. Because this test failure is due to
15199 // requiring a client certificate, this fallback handshake should also
15200 // fail.
ttuttle859dc7a2015-04-23 19:42:2915201 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
Steven Valdez0ef94d02018-11-19 23:28:1315202 ssl_data3.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
[email protected]bd0b6772011-01-11 19:59:3015203 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715204 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115205 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715206 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015207
[email protected]80c75f682012-05-26 16:22:1715208 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
15209 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4215210 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
15211 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1715212 // of the HttpNetworkTransaction. Because this test failure is due to
15213 // requiring a client certificate, this fallback handshake should also
15214 // fail.
ttuttle859dc7a2015-04-23 19:42:2915215 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1715216 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715217 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115218 StaticSocketDataProvider data4;
[email protected]bb88e1d32013-05-03 23:11:0715219 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715220
danakj1fd259a02016-04-16 03:17:0915221 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615222 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015223
[email protected]bd0b6772011-01-11 19:59:3015224 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4115225 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015226 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115227 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015228
15229 // Complete the SSL handshake, which should abort due to requiring a
15230 // client certificate.
15231 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115232 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015233
15234 // Indicate that no certificate should be supplied. From the perspective
15235 // of SSLClientCertCache, NULL is just as meaningful as a real
15236 // certificate, so this is the same as supply a
15237 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515238 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115239 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015240
15241 // Ensure the certificate was added to the client auth cache before
15242 // allowing the connection to continue restarting.
15243 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415244 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115245 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415246 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215247 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015248
15249 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715250 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15251 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015252 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115253 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015254
15255 // Ensure that the client certificate is removed from the cache on a
15256 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115257 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415258 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015259}
15260
15261// Ensure that a client certificate is removed from the SSL client auth
15262// cache when:
15263// 1) No proxy is involved.
15264// 2) TLS False Start is enabled.
15265// 3) The initial TLS handshake requests a client certificate.
15266// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115267TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915268 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715269 request_info.url = GURL("https://www.example.com/");
15270 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915271 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015272 request_info.traffic_annotation =
15273 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715274
[email protected]bd0b6772011-01-11 19:59:3015275 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115276 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015277
15278 // When TLS False Start is used, SSLClientSocket::Connect() calls will
15279 // return successfully after reading up to the peer's Certificate message.
15280 // This is to allow the caller to call SSLClientSocket::Write(), which can
15281 // enqueue application data to be sent in the same packet as the
15282 // ChangeCipherSpec and Finished messages.
15283 // The actual handshake will be finished when SSLClientSocket::Read() is
15284 // called, which expects to process the peer's ChangeCipherSpec and
15285 // Finished messages. If there was an error negotiating with the peer,
15286 // such as due to the peer requiring a client certificate when none was
15287 // supplied, the alert sent by the peer won't be processed until Read() is
15288 // called.
15289
15290 // Like the non-False Start case, when a client certificate is requested by
15291 // the peer, the handshake is aborted during the Connect() call.
15292 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2915293 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015294 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715295 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115296 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715297 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015298
15299 // When a client certificate is supplied, Connect() will not be aborted
15300 // when the peer requests the certificate. Instead, the handshake will
15301 // artificially succeed, allowing the caller to write the HTTP request to
15302 // the socket. The handshake messages are not processed until Read() is
15303 // called, which then detects that the handshake was aborted, due to the
15304 // peer sending a handshake_failure because it requires a client
15305 // certificate.
ttuttle859dc7a2015-04-23 19:42:2915306 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015307 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715308 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2915309 MockRead data2_reads[] = {
15310 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3015311 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115312 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715313 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015314
15315 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1715316 // the data for the SSL handshake once the TLSv1.1 connection falls back to
15317 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915318 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015319 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715320 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115321 StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715322 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015323
[email protected]80c75f682012-05-26 16:22:1715324 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
15325 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915326 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1715327 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715328 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115329 StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715330 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715331
[email protected]7799de12013-05-30 05:52:5115332 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2915333 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5115334 ssl_data5.cert_request_info = cert_request.get();
15335 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
Ryan Sleevib8d7ea02018-05-07 20:01:0115336 StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
[email protected]7799de12013-05-30 05:52:5115337 session_deps_.socket_factory->AddSocketDataProvider(&data5);
15338
danakj1fd259a02016-04-16 03:17:0915339 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615340 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015341
[email protected]bd0b6772011-01-11 19:59:3015342 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4115343 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015344 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115345 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015346
15347 // Complete the SSL handshake, which should abort due to requiring a
15348 // client certificate.
15349 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115350 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015351
15352 // Indicate that no certificate should be supplied. From the perspective
15353 // of SSLClientCertCache, NULL is just as meaningful as a real
15354 // certificate, so this is the same as supply a
15355 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515356 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115357 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015358
15359 // Ensure the certificate was added to the client auth cache before
15360 // allowing the connection to continue restarting.
15361 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415362 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115363 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415364 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215365 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015366
[email protected]bd0b6772011-01-11 19:59:3015367 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715368 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15369 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015370 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115371 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015372
15373 // Ensure that the client certificate is removed from the cache on a
15374 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115375 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415376 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015377}
15378
[email protected]8c405132011-01-11 22:03:1815379// Ensure that a client certificate is removed from the SSL client auth
15380// cache when:
15381// 1) An HTTPS proxy is involved.
15382// 3) The HTTPS proxy requests a client certificate.
15383// 4) The client supplies an invalid/unacceptable certificate for the
15384// proxy.
15385// The test is repeated twice, first for connecting to an HTTPS endpoint,
15386// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0115387TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4915388 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
15389 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115390 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715391 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1815392
15393 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115394 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1815395
15396 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
15397 // [ssl_]data[1-3]. Rather than represending the endpoint
15398 // (www.example.com:443), they represent failures with the HTTPS proxy
15399 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2915400 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1815401 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715402 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115403 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715404 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1815405
ttuttle859dc7a2015-04-23 19:42:2915406 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815407 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715408 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115409 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715410 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1815411
[email protected]80c75f682012-05-26 16:22:1715412 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
15413#if 0
ttuttle859dc7a2015-04-23 19:42:2915414 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815415 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715416 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115417 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715418 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1715419#endif
[email protected]8c405132011-01-11 22:03:1815420
ttuttle859dc7a2015-04-23 19:42:2915421 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1815422 requests[0].url = GURL("https://www.example.com/");
15423 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915424 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015425 requests[0].traffic_annotation =
15426 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815427
15428 requests[1].url = GURL("http://www.example.com/");
15429 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915430 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015431 requests[1].traffic_annotation =
15432 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815433
Avi Drissman4365a4782018-12-28 19:26:2415434 for (size_t i = 0; i < base::size(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0715435 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0915436 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615437 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1815438
15439 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4115440 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015441 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115442 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815443
15444 // Complete the SSL handshake, which should abort due to requiring a
15445 // client certificate.
15446 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115447 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1815448
15449 // Indicate that no certificate should be supplied. From the perspective
15450 // of SSLClientCertCache, NULL is just as meaningful as a real
15451 // certificate, so this is the same as supply a
15452 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515453 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115454 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815455
15456 // Ensure the certificate was added to the client auth cache before
15457 // allowing the connection to continue restarting.
15458 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415459 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115460 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415461 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215462 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1815463 // Ensure the certificate was NOT cached for the endpoint. This only
15464 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4115465 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415466 HostPortPair("www.example.com", 443), &client_cert,
15467 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815468
15469 // Restart the handshake. This will consume ssl_data2, which fails, and
15470 // then consume ssl_data3, which should also fail. The result code is
15471 // checked against what ssl_data3 should return.
15472 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115473 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1815474
15475 // Now that the new handshake has failed, ensure that the client
15476 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4115477 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415478 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4115479 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415480 HostPortPair("www.example.com", 443), &client_cert,
15481 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815482 }
15483}
15484
bncd16676a2016-07-20 16:23:0115485TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4615486 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915487 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915488 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615489
bnc032658ba2016-09-26 18:17:1515490 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615491
Ryan Hamilton0239aac2018-05-19 00:03:1315492 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915493 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815494 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315495 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715496 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615497 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115498 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615499 };
Ryan Hamilton0239aac2018-05-19 00:03:1315500 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515501 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315502 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115503 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315504 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515505 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315506 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115507 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615508 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115509 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15510 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315511 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615512 };
15513
eroman36d84e54432016-03-17 03:23:0215514 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215515 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115516 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715517 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615518
[email protected]aa22b242011-11-16 18:58:2915519 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615520 HttpRequestInfo request1;
15521 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315522 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615523 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015524 request1.traffic_annotation =
15525 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015526 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615527
tfarina42834112016-09-22 13:38:2015528 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115529 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15530 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615531
15532 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215533 ASSERT_TRUE(response);
15534 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215535 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615536
15537 std::string response_data;
robpercival214763f2016-07-01 23:27:0115538 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615539 EXPECT_EQ("hello!", response_data);
15540
bnca4d611d2016-09-22 19:55:3715541 // Preload mail.example.com into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315542 rv = session_deps_.host_resolver->LoadIntoCache(
15543 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115544 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615545
15546 HttpRequestInfo request2;
15547 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715548 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615549 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015550 request2.traffic_annotation =
15551 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015552 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615553
tfarina42834112016-09-22 13:38:2015554 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15556 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615557
15558 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215559 ASSERT_TRUE(response);
15560 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215561 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615562 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215563 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115564 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615565 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615566}
15567
bncd16676a2016-07-20 16:23:0115568TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0215569 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915570 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915571 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0215572
bnc032658ba2016-09-26 18:17:1515573 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0215574
Ryan Hamilton0239aac2018-05-19 00:03:1315575 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915576 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815577 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315578 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715579 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0215580 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115581 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0215582 };
Ryan Hamilton0239aac2018-05-19 00:03:1315583 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515584 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315585 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115586 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315587 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515588 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315589 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115590 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0215591 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115592 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15593 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315594 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0215595 };
15596
eroman36d84e54432016-03-17 03:23:0215597 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215598 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115599 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715600 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0215601
15602 TestCompletionCallback callback;
15603 HttpRequestInfo request1;
15604 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315605 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0215606 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015607 request1.traffic_annotation =
15608 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015609 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215610
tfarina42834112016-09-22 13:38:2015611 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115612 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15613 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215614
15615 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215616 ASSERT_TRUE(response);
15617 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215618 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215619
15620 std::string response_data;
robpercival214763f2016-07-01 23:27:0115621 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215622 EXPECT_EQ("hello!", response_data);
15623
15624 HttpRequestInfo request2;
15625 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715626 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0215627 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015628 request2.traffic_annotation =
15629 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015630 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215631
tfarina42834112016-09-22 13:38:2015632 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115633 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15634 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215635
15636 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215637 ASSERT_TRUE(response);
15638 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215639 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215640 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215641 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115642 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215643 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0215644}
15645
bnc8016c1f2017-03-31 02:11:2915646// Regression test for https://crbug.com/546991.
15647// The server might not be able to serve an IP pooled request, and might send a
15648// 421 Misdirected Request response status to indicate this.
15649// HttpNetworkTransaction should reset the request and retry without IP pooling.
15650TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
15651 // Two hosts resolve to the same IP address.
15652 const std::string ip_addr = "1.2.3.4";
15653 IPAddress ip;
15654 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15655 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15656
Jeremy Roman0579ed62017-08-29 15:56:1915657 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2915658 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15659 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15660
15661 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15662
15663 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315664 spdy::SpdySerializedFrame req1(
bnc8016c1f2017-03-31 02:11:2915665 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15666 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315667 spdy::SpdySerializedFrame req2(
bnc8016c1f2017-03-31 02:11:2915668 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315669 spdy::SpdySerializedFrame rst(
15670 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
bnc8016c1f2017-03-31 02:11:2915671 MockWrite writes1[] = {
15672 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15673 CreateMockWrite(rst, 6),
15674 };
15675
15676 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315677 spdy::SpdySerializedFrame resp1(
15678 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15679 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15680 spdy::SpdyHeaderBlock response_headers;
15681 response_headers[spdy::kHttp2StatusHeader] = "421";
15682 spdy::SpdySerializedFrame resp2(
bnc8016c1f2017-03-31 02:11:2915683 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
15684 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15685 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15686
15687 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115688 SequencedSocketData data1(connect1, reads1, writes1);
bnc8016c1f2017-03-31 02:11:2915689 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15690
15691 AddSSLSocketData();
15692
15693 // Retry the second request on a second connection.
15694 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315695 spdy::SpdySerializedFrame req3(
bnc8016c1f2017-03-31 02:11:2915696 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15697 MockWrite writes2[] = {
15698 CreateMockWrite(req3, 0),
15699 };
15700
Ryan Hamilton0239aac2018-05-19 00:03:1315701 spdy::SpdySerializedFrame resp3(
15702 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
15703 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
bnc8016c1f2017-03-31 02:11:2915704 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15705 MockRead(ASYNC, 0, 3)};
15706
15707 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115708 SequencedSocketData data2(connect2, reads2, writes2);
bnc8016c1f2017-03-31 02:11:2915709 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15710
15711 AddSSLSocketData();
15712
15713 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315714 int rv = session_deps_.host_resolver->LoadIntoCache(
15715 HostPortPair("mail.example.com", 443), base::nullopt);
bnc8016c1f2017-03-31 02:11:2915716 EXPECT_THAT(rv, IsOk());
15717
15718 HttpRequestInfo request1;
15719 request1.method = "GET";
15720 request1.url = GURL("https://www.example.org/");
15721 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015722 request1.traffic_annotation =
15723 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915724 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15725
Eric Orthf4db66a2019-02-19 21:35:3315726 TestCompletionCallback callback;
bnc8016c1f2017-03-31 02:11:2915727 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15728 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15729 rv = callback.WaitForResult();
15730 EXPECT_THAT(rv, IsOk());
15731
15732 const HttpResponseInfo* response = trans1.GetResponseInfo();
15733 ASSERT_TRUE(response);
15734 ASSERT_TRUE(response->headers);
15735 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15736 EXPECT_TRUE(response->was_fetched_via_spdy);
15737 EXPECT_TRUE(response->was_alpn_negotiated);
15738 std::string response_data;
15739 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15740 EXPECT_EQ("hello!", response_data);
15741
15742 HttpRequestInfo request2;
15743 request2.method = "GET";
15744 request2.url = GURL("https://mail.example.org/");
15745 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015746 request2.traffic_annotation =
15747 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915748 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15749
15750 BoundTestNetLog log;
15751 rv = trans2.Start(&request2, callback.callback(), log.bound());
15752 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15753 rv = callback.WaitForResult();
15754 EXPECT_THAT(rv, IsOk());
15755
15756 response = trans2.GetResponseInfo();
15757 ASSERT_TRUE(response);
15758 ASSERT_TRUE(response->headers);
15759 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15760 EXPECT_TRUE(response->was_fetched_via_spdy);
15761 EXPECT_TRUE(response->was_alpn_negotiated);
15762 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15763 EXPECT_EQ("hello!", response_data);
15764
15765 TestNetLogEntry::List entries;
15766 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5915767 ExpectLogContainsSomewhere(
15768 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2915769 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5915770}
15771
15772// Test that HTTP 421 responses are properly returned to the caller if received
15773// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
15774// portions of the response.
15775TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
15776 // Two hosts resolve to the same IP address.
15777 const std::string ip_addr = "1.2.3.4";
15778 IPAddress ip;
15779 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15780 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15781
Jeremy Roman0579ed62017-08-29 15:56:1915782 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5915783 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15784 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15785
15786 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15787
15788 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315789 spdy::SpdySerializedFrame req1(
davidbence688ae2017-05-04 15:12:5915790 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15791 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315792 spdy::SpdySerializedFrame req2(
davidbence688ae2017-05-04 15:12:5915793 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315794 spdy::SpdySerializedFrame rst(
15795 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
davidbence688ae2017-05-04 15:12:5915796 MockWrite writes1[] = {
15797 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15798 CreateMockWrite(rst, 6),
15799 };
15800
15801 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315802 spdy::SpdySerializedFrame resp1(
15803 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15804 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15805 spdy::SpdyHeaderBlock response_headers;
15806 response_headers[spdy::kHttp2StatusHeader] = "421";
15807 spdy::SpdySerializedFrame resp2(
davidbence688ae2017-05-04 15:12:5915808 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
15809 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15810 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15811
15812 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115813 SequencedSocketData data1(connect1, reads1, writes1);
davidbence688ae2017-05-04 15:12:5915814 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15815
15816 AddSSLSocketData();
15817
15818 // Retry the second request on a second connection. It returns 421 Misdirected
15819 // Retry again.
15820 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315821 spdy::SpdySerializedFrame req3(
davidbence688ae2017-05-04 15:12:5915822 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15823 MockWrite writes2[] = {
15824 CreateMockWrite(req3, 0),
15825 };
15826
Ryan Hamilton0239aac2018-05-19 00:03:1315827 spdy::SpdySerializedFrame resp3(
davidbence688ae2017-05-04 15:12:5915828 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
Ryan Hamilton0239aac2018-05-19 00:03:1315829 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
davidbence688ae2017-05-04 15:12:5915830 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15831 MockRead(ASYNC, 0, 3)};
15832
15833 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115834 SequencedSocketData data2(connect2, reads2, writes2);
davidbence688ae2017-05-04 15:12:5915835 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15836
15837 AddSSLSocketData();
15838
15839 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315840 int rv = session_deps_.host_resolver->LoadIntoCache(
15841 HostPortPair("mail.example.com", 443), base::nullopt);
davidbence688ae2017-05-04 15:12:5915842 EXPECT_THAT(rv, IsOk());
15843
15844 HttpRequestInfo request1;
15845 request1.method = "GET";
15846 request1.url = GURL("https://www.example.org/");
15847 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015848 request1.traffic_annotation =
15849 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915850 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15851
Eric Orthf4db66a2019-02-19 21:35:3315852 TestCompletionCallback callback;
davidbence688ae2017-05-04 15:12:5915853 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15854 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15855 rv = callback.WaitForResult();
15856 EXPECT_THAT(rv, IsOk());
15857
15858 const HttpResponseInfo* response = trans1.GetResponseInfo();
15859 ASSERT_TRUE(response);
15860 ASSERT_TRUE(response->headers);
15861 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15862 EXPECT_TRUE(response->was_fetched_via_spdy);
15863 EXPECT_TRUE(response->was_alpn_negotiated);
15864 std::string response_data;
15865 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15866 EXPECT_EQ("hello!", response_data);
15867
15868 HttpRequestInfo request2;
15869 request2.method = "GET";
15870 request2.url = GURL("https://mail.example.org/");
15871 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015872 request2.traffic_annotation =
15873 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915874 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15875
15876 BoundTestNetLog log;
15877 rv = trans2.Start(&request2, callback.callback(), log.bound());
15878 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15879 rv = callback.WaitForResult();
15880 EXPECT_THAT(rv, IsOk());
15881
15882 // After a retry, the 421 Misdirected Request is reported back up to the
15883 // caller.
15884 response = trans2.GetResponseInfo();
15885 ASSERT_TRUE(response);
15886 ASSERT_TRUE(response->headers);
15887 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
15888 EXPECT_TRUE(response->was_fetched_via_spdy);
15889 EXPECT_TRUE(response->was_alpn_negotiated);
15890 EXPECT_TRUE(response->ssl_info.cert);
15891 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15892 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2915893}
15894
bncd16676a2016-07-20 16:23:0115895TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1315896 UseIPConnectionPoolingWithHostCacheExpiration) {
Eric Orth1da75de2019-02-20 21:10:3415897 // Set up HostResolver to invalidate cached entries after 1 cached resolve.
15898 session_deps_.host_resolver =
15899 std::make_unique<MockCachingHostResolver>(1 /* cache_invalidation_num */);
danakj1fd259a02016-04-16 03:17:0915900 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615901
bnc032658ba2016-09-26 18:17:1515902 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615903
Ryan Hamilton0239aac2018-05-19 00:03:1315904 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915905 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815906 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315907 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715908 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615909 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115910 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615911 };
Ryan Hamilton0239aac2018-05-19 00:03:1315912 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515913 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315914 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115915 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315916 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515917 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315918 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115919 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615920 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115921 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15922 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315923 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615924 };
15925
eroman36d84e54432016-03-17 03:23:0215926 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215927 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115928 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715929 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615930
[email protected]aa22b242011-11-16 18:58:2915931 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615932 HttpRequestInfo request1;
15933 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315934 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615935 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015936 request1.traffic_annotation =
15937 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015938 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615939
tfarina42834112016-09-22 13:38:2015940 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115941 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15942 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615943
15944 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215945 ASSERT_TRUE(response);
15946 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215947 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615948
15949 std::string response_data;
robpercival214763f2016-07-01 23:27:0115950 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615951 EXPECT_EQ("hello!", response_data);
15952
15953 // Preload cache entries into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315954 rv = session_deps_.host_resolver->LoadIntoCache(
15955 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115956 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615957
15958 HttpRequestInfo request2;
15959 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715960 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615961 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015962 request2.traffic_annotation =
15963 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015964 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615965
tfarina42834112016-09-22 13:38:2015966 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115967 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15968 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615969
15970 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215971 ASSERT_TRUE(response);
15972 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215973 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615974 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215975 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115976 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615977 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615978}
15979
bncd16676a2016-07-20 16:23:0115980TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315981 const std::string https_url = "https://www.example.org:8080/";
15982 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415983
15984 // SPDY GET for HTTPS URL
Ryan Hamilton0239aac2018-05-19 00:03:1315985 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915986 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415987
15988 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115989 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415990 };
15991
Raul Tambre94493c652019-03-11 17:18:3515992 spdy::SpdySerializedFrame resp1(
15993 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315994 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4115995 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915996 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415997
Ryan Sleevib8d7ea02018-05-07 20:01:0115998 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415999 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5716000 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0416001
16002 // HTTP GET for the HTTP URL
16003 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1316004 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3416005 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316006 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3416007 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0416008 };
16009
16010 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1316011 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
16012 MockRead(ASYNC, 2, "hello"),
16013 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0416014 };
16015
Ryan Sleevib8d7ea02018-05-07 20:01:0116016 SequencedSocketData data2(reads2, writes2);
[email protected]8450d722012-07-02 19:14:0416017
[email protected]8450d722012-07-02 19:14:0416018 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616019 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0716020 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16021 session_deps_.socket_factory->AddSocketDataProvider(&data1);
16022 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0416023
danakj1fd259a02016-04-16 03:17:0916024 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0416025
16026 // Start the first transaction to set up the SpdySession
16027 HttpRequestInfo request1;
16028 request1.method = "GET";
16029 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0416030 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016031 request1.traffic_annotation =
16032 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016033 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0416034 TestCompletionCallback callback1;
16035 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016036 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516037 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0416038
robpercival214763f2016-07-01 23:27:0116039 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0416040 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16041
16042 // Now, start the HTTP request
16043 HttpRequestInfo request2;
16044 request2.method = "GET";
16045 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0416046 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016047 request2.traffic_annotation =
16048 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016049 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0416050 TestCompletionCallback callback2;
16051 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016052 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516053 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0416054
robpercival214763f2016-07-01 23:27:0116055 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0416056 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16057}
16058
bnc5452e2a2015-05-08 16:27:4216059// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
16060// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0116061TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2516062 url::SchemeHostPort server("https", "www.example.org", 443);
16063 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4216064
bnc8bef8da22016-05-30 01:28:2516065 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4216066 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616067 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216068 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16069
16070 // No data should be read from the alternative, because HTTP/1.1 is
16071 // negotiated.
16072 StaticSocketDataProvider data;
16073 session_deps_.socket_factory->AddSocketDataProvider(&data);
16074
16075 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4616076 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4216077 // mocked. This way the request relies on the alternate Job.
16078 StaticSocketDataProvider data_refused;
16079 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16080 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16081
zhongyi3d4a55e72016-04-22 20:36:4616082 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916083 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016084 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216085 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116086 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216087 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116088 http_server_properties->SetHttp2AlternativeService(
16089 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216090
bnc5452e2a2015-05-08 16:27:4216091 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4616092 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216093 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2516094 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e62018-02-07 07:41:1016095 request.traffic_annotation =
16096 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216097 TestCompletionCallback callback;
16098
16099 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5216100 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2016101 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5216102 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4216103}
16104
bnc40448a532015-05-11 19:13:1416105// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4616106// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1416107// succeeds, the request should succeed, even if the latter fails because
16108// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0116109TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2516110 url::SchemeHostPort server("https", "www.example.org", 443);
16111 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1416112
16113 // Negotiate HTTP/1.1 with alternative.
16114 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616115 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416116 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
16117
16118 // No data should be read from the alternative, because HTTP/1.1 is
16119 // negotiated.
16120 StaticSocketDataProvider data;
16121 session_deps_.socket_factory->AddSocketDataProvider(&data);
16122
zhongyi3d4a55e72016-04-22 20:36:4616123 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1416124 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616125 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416126 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
16127
16128 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2516129 MockWrite("GET / HTTP/1.1\r\n"
16130 "Host: www.example.org\r\n"
16131 "Connection: keep-alive\r\n\r\n"),
16132 MockWrite("GET /second HTTP/1.1\r\n"
16133 "Host: www.example.org\r\n"
16134 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1416135 };
16136
16137 MockRead http_reads[] = {
16138 MockRead("HTTP/1.1 200 OK\r\n"),
16139 MockRead("Content-Type: text/html\r\n"),
16140 MockRead("Content-Length: 6\r\n\r\n"),
16141 MockRead("foobar"),
16142 MockRead("HTTP/1.1 200 OK\r\n"),
16143 MockRead("Content-Type: text/html\r\n"),
16144 MockRead("Content-Length: 7\r\n\r\n"),
16145 MockRead("another"),
16146 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116147 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc40448a532015-05-11 19:13:1416148 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16149
zhongyi3d4a55e72016-04-22 20:36:4616150 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916151 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016152 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1416153 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116154 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216155 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116156 http_server_properties->SetHttp2AlternativeService(
16157 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1416158
16159 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
16160 HttpRequestInfo request1;
16161 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2516162 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1416163 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016164 request1.traffic_annotation =
16165 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416166 TestCompletionCallback callback1;
16167
tfarina42834112016-09-22 13:38:2016168 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416169 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116170 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416171
16172 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5216173 ASSERT_TRUE(response1);
16174 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1416175 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
16176
16177 std::string response_data1;
robpercival214763f2016-07-01 23:27:0116178 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1416179 EXPECT_EQ("foobar", response_data1);
16180
16181 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
16182 // for alternative service.
16183 EXPECT_TRUE(
16184 http_server_properties->IsAlternativeServiceBroken(alternative_service));
16185
zhongyi3d4a55e72016-04-22 20:36:4616186 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1416187 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4616188 // to server.
bnc40448a532015-05-11 19:13:1416189 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
16190 HttpRequestInfo request2;
16191 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2516192 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1416193 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016194 request2.traffic_annotation =
16195 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416196 TestCompletionCallback callback2;
16197
tfarina42834112016-09-22 13:38:2016198 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416199 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116200 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416201
16202 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216203 ASSERT_TRUE(response2);
16204 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1416205 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
16206
16207 std::string response_data2;
robpercival214763f2016-07-01 23:27:0116208 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1416209 EXPECT_EQ("another", response_data2);
16210}
16211
bnc5452e2a2015-05-08 16:27:4216212// Alternative service requires HTTP/2 (or SPDY), but there is already a
16213// HTTP/1.1 socket open to the alternative server. That socket should not be
16214// used.
bncd16676a2016-07-20 16:23:0116215TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4616216 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4216217 HostPortPair alternative("alternative.example.org", 443);
16218 std::string origin_url = "https://origin.example.org:443";
16219 std::string alternative_url = "https://alternative.example.org:443";
16220
16221 // Negotiate HTTP/1.1 with alternative.example.org.
16222 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616223 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216224 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16225
16226 // HTTP/1.1 data for |request1| and |request2|.
16227 MockWrite http_writes[] = {
16228 MockWrite(
16229 "GET / HTTP/1.1\r\n"
16230 "Host: alternative.example.org\r\n"
16231 "Connection: keep-alive\r\n\r\n"),
16232 MockWrite(
16233 "GET / HTTP/1.1\r\n"
16234 "Host: alternative.example.org\r\n"
16235 "Connection: keep-alive\r\n\r\n"),
16236 };
16237
16238 MockRead http_reads[] = {
16239 MockRead(
16240 "HTTP/1.1 200 OK\r\n"
16241 "Content-Type: text/html; charset=iso-8859-1\r\n"
16242 "Content-Length: 40\r\n\r\n"
16243 "first HTTP/1.1 response from alternative"),
16244 MockRead(
16245 "HTTP/1.1 200 OK\r\n"
16246 "Content-Type: text/html; charset=iso-8859-1\r\n"
16247 "Content-Length: 41\r\n\r\n"
16248 "second HTTP/1.1 response from alternative"),
16249 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116250 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc5452e2a2015-05-08 16:27:4216251 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16252
16253 // This test documents that an alternate Job should not pool to an already
16254 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4616255 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4216256 StaticSocketDataProvider data_refused;
16257 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16258 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16259
zhongyi3d4a55e72016-04-22 20:36:4616260 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916261 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016262 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216263 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116264 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216265 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116266 http_server_properties->SetHttp2AlternativeService(
16267 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216268
16269 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4216270 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4616271 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216272 request1.method = "GET";
16273 request1.url = GURL(alternative_url);
16274 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016275 request1.traffic_annotation =
16276 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216277 TestCompletionCallback callback1;
16278
tfarina42834112016-09-22 13:38:2016279 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116280 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616281 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216282 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5216283 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4216284 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216285 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216286 EXPECT_FALSE(response1->was_fetched_via_spdy);
16287 std::string response_data1;
bnc691fda62016-08-12 00:43:1616288 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4216289 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
16290
16291 // Request for origin.example.org, which has an alternative service. This
16292 // will start two Jobs: the alternative looks for connections to pool to,
16293 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4616294 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4216295 // this request fails.
bnc5452e2a2015-05-08 16:27:4216296 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4616297 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216298 request2.method = "GET";
16299 request2.url = GURL(origin_url);
16300 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016301 request2.traffic_annotation =
16302 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216303 TestCompletionCallback callback2;
16304
tfarina42834112016-09-22 13:38:2016305 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116306 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4216307
16308 // Another transaction to alternative. This is to test that the HTTP/1.1
16309 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4216310 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4616311 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216312 request3.method = "GET";
16313 request3.url = GURL(alternative_url);
16314 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016315 request3.traffic_annotation =
16316 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216317 TestCompletionCallback callback3;
16318
tfarina42834112016-09-22 13:38:2016319 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116320 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616321 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216322 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5216323 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4216324 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216325 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216326 EXPECT_FALSE(response3->was_fetched_via_spdy);
16327 std::string response_data3;
bnc691fda62016-08-12 00:43:1616328 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4216329 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
16330}
16331
bncd16676a2016-07-20 16:23:0116332TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2316333 const std::string https_url = "https://www.example.org:8080/";
16334 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0416335
rdsmithebb50aa2015-11-12 03:44:3816336 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0116337 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3816338
[email protected]8450d722012-07-02 19:14:0416339 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2316340 const HostPortPair host_port_pair("www.example.org", 8080);
Matt Menke6e879bd2019-03-18 17:26:0416341 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
16342 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
16343 host_port_pair));
Ryan Hamilton0239aac2018-05-19 00:03:1316344 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4916345 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1316346 spdy::SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0216347 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3916348
16349 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
Ryan Hamilton0239aac2018-05-19 00:03:1316350 spdy::SpdyHeaderBlock req2_block;
16351 req2_block[spdy::kHttp2MethodHeader] = "GET";
16352 req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
16353 req2_block[spdy::kHttp2SchemeHeader] = "http";
16354 req2_block[spdy::kHttp2PathHeader] = "/";
16355 spdy::SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1516356 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0416357
16358 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116359 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
16360 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0416361 };
16362
Ryan Hamilton0239aac2018-05-19 00:03:1316363 spdy::SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1516364 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316365 spdy::SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1516366 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316367 spdy::SpdySerializedFrame body1(
16368 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
16369 spdy::SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3816370 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316371 spdy::SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3816372 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
Raul Tambre94493c652019-03-11 17:18:3516373 spdy::SpdySerializedFrame resp2(
16374 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1316375 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3316376 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116377 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3316378 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4116379 CreateMockRead(wrapped_resp1, 4),
16380 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3316381 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4116382 CreateMockRead(resp2, 8),
16383 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3316384 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
16385 };
[email protected]8450d722012-07-02 19:14:0416386
Ryan Sleevib8d7ea02018-05-07 20:01:0116387 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0416388 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5716389 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0416390
Lily Houghton8c2f97d2018-01-22 05:06:5916391 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916392 ProxyResolutionService::CreateFixedFromPacResult(
16393 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5116394 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0716395 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0416396 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616397 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316398 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0416399 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616400 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316401 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16402 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0416403
danakj1fd259a02016-04-16 03:17:0916404 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0416405
16406 // Start the first transaction to set up the SpdySession
16407 HttpRequestInfo request1;
16408 request1.method = "GET";
16409 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0416410 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016411 request1.traffic_annotation =
16412 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016413 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0416414 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2016415 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416416
mmenke666a6fea2015-12-19 04:16:3316417 // This pause is a hack to avoid running into https://crbug.com/497228.
16418 data1.RunUntilPaused();
16419 base::RunLoop().RunUntilIdle();
16420 data1.Resume();
robpercival214763f2016-07-01 23:27:0116421 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0416422 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16423
[email protected]f6c63db52013-02-02 00:35:2216424 LoadTimingInfo load_timing_info1;
16425 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
16426 TestLoadTimingNotReusedWithPac(load_timing_info1,
16427 CONNECT_TIMING_HAS_SSL_TIMES);
16428
mmenke666a6fea2015-12-19 04:16:3316429 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0416430 HttpRequestInfo request2;
16431 request2.method = "GET";
16432 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0416433 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016434 request2.traffic_annotation =
16435 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016436 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0416437 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2016438 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416439
mmenke666a6fea2015-12-19 04:16:3316440 // This pause is a hack to avoid running into https://crbug.com/497228.
16441 data1.RunUntilPaused();
16442 base::RunLoop().RunUntilIdle();
16443 data1.Resume();
robpercival214763f2016-07-01 23:27:0116444 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3316445
[email protected]8450d722012-07-02 19:14:0416446 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2216447
16448 LoadTimingInfo load_timing_info2;
16449 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
16450 // The established SPDY sessions is considered reused by the HTTP request.
16451 TestLoadTimingReusedWithPac(load_timing_info2);
16452 // HTTP requests over a SPDY session should have a different connection
16453 // socket_log_id than requests over a tunnel.
16454 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0416455}
16456
[email protected]2d88e7d2012-07-19 17:55:1716457// Test that in the case where we have a SPDY session to a SPDY proxy
16458// that we do not pool other origins that resolve to the same IP when
16459// the certificate does not match the new origin.
16460// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0116461TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2316462 const std::string url1 = "http://www.example.org/";
16463 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1716464 const std::string ip_addr = "1.2.3.4";
16465
rdsmithebb50aa2015-11-12 03:44:3816466 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0116467 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3816468
[email protected]2d88e7d2012-07-19 17:55:1716469 // SPDY GET for HTTP URL (through SPDY proxy)
Ryan Hamilton0239aac2018-05-19 00:03:1316470 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2316471 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:1316472 spdy::SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1516473 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1716474
16475 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116476 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1716477 };
16478
Raul Tambre94493c652019-03-11 17:18:3516479 spdy::SpdySerializedFrame resp1(
16480 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316481 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1716482 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116483 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
16484 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1716485 };
16486
Ryan Sleevib8d7ea02018-05-07 20:01:0116487 SequencedSocketData data1(reads1, writes1);
martijnfe9636e2016-02-06 14:33:3216488 IPAddress ip;
martijn654c8c42016-02-10 22:10:5916489 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1716490 IPEndPoint peer_addr = IPEndPoint(ip, 443);
16491 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3316492 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1716493
16494 // SPDY GET for HTTPS URL (direct)
Ryan Hamilton0239aac2018-05-19 00:03:1316495 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916496 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1716497
16498 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116499 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1716500 };
16501
Ryan Hamilton0239aac2018-05-19 00:03:1316502 spdy::SpdySerializedFrame resp2(
Raul Tambre94493c652019-03-11 17:18:3516503 spdy_util_secure.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316504 spdy::SpdySerializedFrame body2(
16505 spdy_util_secure.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4116506 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3316507 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1716508
Ryan Sleevib8d7ea02018-05-07 20:01:0116509 SequencedSocketData data2(reads2, writes2);
[email protected]2d88e7d2012-07-19 17:55:1716510 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3316511 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1716512
16513 // Set up a proxy config that sends HTTP requests to a proxy, and
16514 // all others direct.
16515 ProxyConfig proxy_config;
16516 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4916517 session_deps_.proxy_resolution_service =
16518 std::make_unique<ProxyResolutionService>(
16519 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
16520 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
16521 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1716522
bncce36dca22015-04-21 22:11:2316523 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616524 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1716525 // Load a valid cert. Note, that this does not need to
16526 // be valid for proxy because the MockSSLClientSocket does
16527 // not actually verify it. But SpdySession will use this
16528 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4916529 ssl1.ssl_info.cert =
16530 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
16531 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3316532 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16533 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1716534
16535 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616536 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316537 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16538 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1716539
Jeremy Roman0579ed62017-08-29 15:56:1916540 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2316541 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0716542 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1716543
danakj1fd259a02016-04-16 03:17:0916544 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1716545
16546 // Start the first transaction to set up the SpdySession
16547 HttpRequestInfo request1;
16548 request1.method = "GET";
16549 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1716550 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016551 request1.traffic_annotation =
16552 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016553 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716554 TestCompletionCallback callback1;
16555 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016556 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3316557 // This pause is a hack to avoid running into https://crbug.com/497228.
16558 data1.RunUntilPaused();
16559 base::RunLoop().RunUntilIdle();
16560 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1716561
robpercival214763f2016-07-01 23:27:0116562 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716563 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16564
16565 // Now, start the HTTP request
16566 HttpRequestInfo request2;
16567 request2.method = "GET";
16568 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1716569 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016570 request2.traffic_annotation =
16571 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016572 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716573 TestCompletionCallback callback2;
16574 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016575 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516576 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1716577
16578 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0116579 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716580 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16581}
16582
[email protected]85f97342013-04-17 06:12:2416583// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
16584// error) in SPDY session, removes the socket from pool and closes the SPDY
16585// session. Verify that new url's from the same HttpNetworkSession (and a new
16586// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0116587TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2316588 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2416589
16590 MockRead reads1[] = {
16591 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
16592 };
16593
Ryan Sleevib8d7ea02018-05-07 20:01:0116594 SequencedSocketData data1(reads1, base::span<MockWrite>());
[email protected]85f97342013-04-17 06:12:2416595
Ryan Hamilton0239aac2018-05-19 00:03:1316596 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916597 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2416598 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116599 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2416600 };
16601
Raul Tambre94493c652019-03-11 17:18:3516602 spdy::SpdySerializedFrame resp2(
16603 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316604 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2416605 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4116606 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
16607 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2416608 };
16609
Ryan Sleevib8d7ea02018-05-07 20:01:0116610 SequencedSocketData data2(reads2, writes2);
[email protected]85f97342013-04-17 06:12:2416611
[email protected]85f97342013-04-17 06:12:2416612 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616613 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016614 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16615 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2416616
16617 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616618 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016619 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16620 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2416621
danakj1fd259a02016-04-16 03:17:0916622 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5016623 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2416624
16625 // Start the first transaction to set up the SpdySession and verify that
16626 // connection was closed.
16627 HttpRequestInfo request1;
16628 request1.method = "GET";
16629 request1.url = GURL(https_url);
16630 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016631 request1.traffic_annotation =
16632 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016633 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416634 TestCompletionCallback callback1;
16635 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016636 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116637 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2416638
16639 // Now, start the second request and make sure it succeeds.
16640 HttpRequestInfo request2;
16641 request2.method = "GET";
16642 request2.url = GURL(https_url);
16643 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016644 request2.traffic_annotation =
16645 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016646 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416647 TestCompletionCallback callback2;
16648 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016649 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2416650
robpercival214763f2016-07-01 23:27:0116651 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2416652 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16653}
16654
bncd16676a2016-07-20 16:23:0116655TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0316656 ClientSocketPoolManager::set_max_sockets_per_group(
16657 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16658 ClientSocketPoolManager::set_max_sockets_per_pool(
16659 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16660
16661 // Use two different hosts with different IPs so they don't get pooled.
16662 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
16663 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0916664 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0316665
16666 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616667 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316668 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616669 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316670 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16671 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16672
Ryan Hamilton0239aac2018-05-19 00:03:1316673 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4916674 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316675 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116676 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0316677 };
Ryan Hamilton0239aac2018-05-19 00:03:1316678 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3516679 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316680 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4116681 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316682 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116683 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916684 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316685 };
16686
rdsmithebb50aa2015-11-12 03:44:3816687 // Use a separate test instance for the separate SpdySession that will be
16688 // created.
bncd16676a2016-07-20 16:23:0116689 SpdyTestUtil spdy_util_2;
Ryan Sleevib8d7ea02018-05-07 20:01:0116690 SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
Bence Béky53a5aef2018-03-29 21:54:1216691 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0316692
Ryan Hamilton0239aac2018-05-19 00:03:1316693 spdy::SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4916694 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316695 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116696 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0316697 };
Ryan Hamilton0239aac2018-05-19 00:03:1316698 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3516699 spdy_util_2.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316700 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4116701 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316702 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116703 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916704 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316705 };
16706
Ryan Sleevib8d7ea02018-05-07 20:01:0116707 SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
Bence Béky53a5aef2018-03-29 21:54:1216708 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0316709
16710 MockWrite http_write[] = {
16711 MockWrite("GET / HTTP/1.1\r\n"
16712 "Host: www.a.com\r\n"
16713 "Connection: keep-alive\r\n\r\n"),
16714 };
16715
16716 MockRead http_read[] = {
16717 MockRead("HTTP/1.1 200 OK\r\n"),
16718 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16719 MockRead("Content-Length: 6\r\n\r\n"),
16720 MockRead("hello!"),
16721 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116722 StaticSocketDataProvider http_data(http_read, http_write);
[email protected]483fa202013-05-14 01:07:0316723 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16724
16725 HostPortPair host_port_pair_a("www.a.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116726 SpdySessionKey spdy_session_key_a(
16727 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16728 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316729 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616730 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316731
16732 TestCompletionCallback callback;
16733 HttpRequestInfo request1;
16734 request1.method = "GET";
16735 request1.url = GURL("https://www.a.com/");
16736 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016737 request1.traffic_annotation =
16738 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816739 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916740 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316741
tfarina42834112016-09-22 13:38:2016742 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116743 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16744 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316745
16746 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216747 ASSERT_TRUE(response);
16748 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216749 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316750 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216751 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0316752
16753 std::string response_data;
robpercival214763f2016-07-01 23:27:0116754 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316755 EXPECT_EQ("hello!", response_data);
16756 trans.reset();
16757 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616758 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316759
16760 HostPortPair host_port_pair_b("www.b.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116761 SpdySessionKey spdy_session_key_b(
16762 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16763 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316764 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616765 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316766 HttpRequestInfo request2;
16767 request2.method = "GET";
16768 request2.url = GURL("https://www.b.com/");
16769 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016770 request2.traffic_annotation =
16771 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816772 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916773 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316774
tfarina42834112016-09-22 13:38:2016775 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116776 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16777 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316778
16779 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216780 ASSERT_TRUE(response);
16781 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216782 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316783 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216784 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116785 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316786 EXPECT_EQ("hello!", response_data);
16787 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616788 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316789 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616790 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316791
16792 HostPortPair host_port_pair_a1("www.a.com", 80);
Matt Menke2436b2f2018-12-11 18:07:1116793 SpdySessionKey spdy_session_key_a1(
16794 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16795 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316796 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616797 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0316798 HttpRequestInfo request3;
16799 request3.method = "GET";
16800 request3.url = GURL("http://www.a.com/");
16801 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016802 request3.traffic_annotation =
16803 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816804 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916805 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316806
tfarina42834112016-09-22 13:38:2016807 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116808 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16809 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316810
16811 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216812 ASSERT_TRUE(response);
16813 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0316814 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16815 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216816 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116817 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316818 EXPECT_EQ("hello!", response_data);
16819 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616820 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316821 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616822 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316823}
16824
bncd16676a2016-07-20 16:23:0116825TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416826 HttpRequestInfo request;
16827 request.method = "GET";
bncce36dca22015-04-21 22:11:2316828 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016829 request.traffic_annotation =
16830 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416831
danakj1fd259a02016-04-16 03:17:0916832 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616833 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416834
ttuttled9dbc652015-09-29 20:00:5916835 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416836 StaticSocketDataProvider data;
16837 data.set_connect_data(mock_connect);
16838 session_deps_.socket_factory->AddSocketDataProvider(&data);
16839
16840 TestCompletionCallback callback;
16841
tfarina42834112016-09-22 13:38:2016842 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116843 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416844
16845 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116846 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416847
[email protected]79e1fd62013-06-20 06:50:0416848 // We don't care whether this succeeds or fails, but it shouldn't crash.
16849 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616850 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716851
16852 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616853 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716854 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116855 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916856
16857 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616858 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916859 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416860}
16861
bncd16676a2016-07-20 16:23:0116862TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416863 HttpRequestInfo request;
16864 request.method = "GET";
bncce36dca22015-04-21 22:11:2316865 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016866 request.traffic_annotation =
16867 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416868
danakj1fd259a02016-04-16 03:17:0916869 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616870 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416871
ttuttled9dbc652015-09-29 20:00:5916872 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416873 StaticSocketDataProvider data;
16874 data.set_connect_data(mock_connect);
16875 session_deps_.socket_factory->AddSocketDataProvider(&data);
16876
16877 TestCompletionCallback callback;
16878
tfarina42834112016-09-22 13:38:2016879 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416881
16882 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116883 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416884
[email protected]79e1fd62013-06-20 06:50:0416885 // We don't care whether this succeeds or fails, but it shouldn't crash.
16886 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616887 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716888
16889 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616890 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716891 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116892 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916893
16894 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616895 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916896 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416897}
16898
bncd16676a2016-07-20 16:23:0116899TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416900 HttpRequestInfo request;
16901 request.method = "GET";
bncce36dca22015-04-21 22:11:2316902 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016903 request.traffic_annotation =
16904 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416905
danakj1fd259a02016-04-16 03:17:0916906 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616907 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416908
16909 MockWrite data_writes[] = {
16910 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16911 };
16912 MockRead data_reads[] = {
16913 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16914 };
16915
Ryan Sleevib8d7ea02018-05-07 20:01:0116916 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416917 session_deps_.socket_factory->AddSocketDataProvider(&data);
16918
16919 TestCompletionCallback callback;
16920
tfarina42834112016-09-22 13:38:2016921 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116922 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416923
16924 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116925 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416926
[email protected]79e1fd62013-06-20 06:50:0416927 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616928 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416929 EXPECT_TRUE(request_headers.HasHeader("Host"));
16930}
16931
bncd16676a2016-07-20 16:23:0116932TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416933 HttpRequestInfo request;
16934 request.method = "GET";
bncce36dca22015-04-21 22:11:2316935 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016936 request.traffic_annotation =
16937 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416938
danakj1fd259a02016-04-16 03:17:0916939 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616940 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416941
16942 MockWrite data_writes[] = {
16943 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16944 };
16945 MockRead data_reads[] = {
16946 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16947 };
16948
Ryan Sleevib8d7ea02018-05-07 20:01:0116949 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416950 session_deps_.socket_factory->AddSocketDataProvider(&data);
16951
16952 TestCompletionCallback callback;
16953
tfarina42834112016-09-22 13:38:2016954 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116955 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416956
16957 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116958 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416959
[email protected]79e1fd62013-06-20 06:50:0416960 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616961 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416962 EXPECT_TRUE(request_headers.HasHeader("Host"));
16963}
16964
bncd16676a2016-07-20 16:23:0116965TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416966 HttpRequestInfo request;
16967 request.method = "GET";
bncce36dca22015-04-21 22:11:2316968 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016969 request.traffic_annotation =
16970 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416971
danakj1fd259a02016-04-16 03:17:0916972 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616973 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416974
16975 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316976 MockWrite(
16977 "GET / HTTP/1.1\r\n"
16978 "Host: www.example.org\r\n"
16979 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416980 };
16981 MockRead data_reads[] = {
16982 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16983 };
16984
Ryan Sleevib8d7ea02018-05-07 20:01:0116985 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416986 session_deps_.socket_factory->AddSocketDataProvider(&data);
16987
16988 TestCompletionCallback callback;
16989
tfarina42834112016-09-22 13:38:2016990 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116991 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416992
16993 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116994 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416995
[email protected]79e1fd62013-06-20 06:50:0416996 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616997 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416998 EXPECT_TRUE(request_headers.HasHeader("Host"));
16999}
17000
bncd16676a2016-07-20 16:23:0117001TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0417002 HttpRequestInfo request;
17003 request.method = "GET";
bncce36dca22015-04-21 22:11:2317004 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017005 request.traffic_annotation =
17006 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0417007
danakj1fd259a02016-04-16 03:17:0917008 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617009 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0417010
17011 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2317012 MockWrite(
17013 "GET / HTTP/1.1\r\n"
17014 "Host: www.example.org\r\n"
17015 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0417016 };
17017 MockRead data_reads[] = {
17018 MockRead(ASYNC, ERR_CONNECTION_RESET),
17019 };
17020
Ryan Sleevib8d7ea02018-05-07 20:01:0117021 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0417022 session_deps_.socket_factory->AddSocketDataProvider(&data);
17023
17024 TestCompletionCallback callback;
17025
tfarina42834112016-09-22 13:38:2017026 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117027 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0417028
17029 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117030 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0417031
[email protected]79e1fd62013-06-20 06:50:0417032 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1617033 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0417034 EXPECT_TRUE(request_headers.HasHeader("Host"));
17035}
17036
bncd16676a2016-07-20 16:23:0117037TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0417038 HttpRequestInfo request;
17039 request.method = "GET";
bncce36dca22015-04-21 22:11:2317040 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0417041 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:1017042 request.traffic_annotation =
17043 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0417044
danakj1fd259a02016-04-16 03:17:0917045 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617046 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0417047
17048 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2317049 MockWrite(
17050 "GET / HTTP/1.1\r\n"
17051 "Host: www.example.org\r\n"
17052 "Connection: keep-alive\r\n"
17053 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0417054 };
17055 MockRead data_reads[] = {
17056 MockRead("HTTP/1.1 200 OK\r\n"
17057 "Content-Length: 5\r\n\r\n"
17058 "hello"),
17059 MockRead(ASYNC, ERR_UNEXPECTED),
17060 };
17061
Ryan Sleevib8d7ea02018-05-07 20:01:0117062 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0417063 session_deps_.socket_factory->AddSocketDataProvider(&data);
17064
17065 TestCompletionCallback callback;
17066
tfarina42834112016-09-22 13:38:2017067 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117068 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0417069
17070 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117071 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0417072
17073 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1617074 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0417075 std::string foo;
17076 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
17077 EXPECT_EQ("bar", foo);
17078}
17079
[email protected]043b68c82013-08-22 23:41:5217080// Tests that when a used socket is returned to the SSL socket pool, it's closed
17081// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117082TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5217083 ClientSocketPoolManager::set_max_sockets_per_group(
17084 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17085 ClientSocketPoolManager::set_max_sockets_per_pool(
17086 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17087
17088 // Set up SSL request.
17089
17090 HttpRequestInfo ssl_request;
17091 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2317092 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017093 ssl_request.traffic_annotation =
17094 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217095
17096 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2317097 MockWrite(
17098 "GET / HTTP/1.1\r\n"
17099 "Host: www.example.org\r\n"
17100 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217101 };
17102 MockRead ssl_reads[] = {
17103 MockRead("HTTP/1.1 200 OK\r\n"),
17104 MockRead("Content-Length: 11\r\n\r\n"),
17105 MockRead("hello world"),
17106 MockRead(SYNCHRONOUS, OK),
17107 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117108 StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
[email protected]043b68c82013-08-22 23:41:5217109 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17110
17111 SSLSocketDataProvider ssl(ASYNC, OK);
17112 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17113
17114 // Set up HTTP request.
17115
17116 HttpRequestInfo http_request;
17117 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317118 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017119 http_request.traffic_annotation =
17120 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217121
17122 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317123 MockWrite(
17124 "GET / HTTP/1.1\r\n"
17125 "Host: www.example.org\r\n"
17126 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217127 };
17128 MockRead http_reads[] = {
17129 MockRead("HTTP/1.1 200 OK\r\n"),
17130 MockRead("Content-Length: 7\r\n\r\n"),
17131 MockRead("falafel"),
17132 MockRead(SYNCHRONOUS, OK),
17133 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117134 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217135 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17136
danakj1fd259a02016-04-16 03:17:0917137 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217138
17139 // Start the SSL request.
17140 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1617141 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017142 ASSERT_EQ(ERR_IO_PENDING,
17143 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
17144 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5217145
17146 // Start the HTTP request. Pool should stall.
17147 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617148 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017149 ASSERT_EQ(ERR_IO_PENDING,
17150 http_trans.Start(&http_request, http_callback.callback(),
17151 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117152 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217153
17154 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0117155 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217156 std::string response_data;
bnc691fda62016-08-12 00:43:1617157 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217158 EXPECT_EQ("hello world", response_data);
17159
17160 // The SSL socket should automatically be closed, so the HTTP request can
17161 // start.
Matt Menke9d5e2c92019-02-05 01:42:2317162 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
dcheng48459ac22014-08-26 00:46:4117163 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217164
17165 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0117166 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1617167 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217168 EXPECT_EQ("falafel", response_data);
17169
dcheng48459ac22014-08-26 00:46:4117170 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217171}
17172
17173// Tests that when a SSL connection is established but there's no corresponding
17174// request that needs it, the new socket is closed if the transport socket pool
17175// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117176TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5217177 ClientSocketPoolManager::set_max_sockets_per_group(
17178 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17179 ClientSocketPoolManager::set_max_sockets_per_pool(
17180 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17181
17182 // Set up an ssl request.
17183
17184 HttpRequestInfo ssl_request;
17185 ssl_request.method = "GET";
17186 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1017187 ssl_request.traffic_annotation =
17188 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217189
17190 // No data will be sent on the SSL socket.
17191 StaticSocketDataProvider ssl_data;
17192 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17193
17194 SSLSocketDataProvider ssl(ASYNC, OK);
17195 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17196
17197 // Set up HTTP request.
17198
17199 HttpRequestInfo http_request;
17200 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317201 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017202 http_request.traffic_annotation =
17203 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217204
17205 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317206 MockWrite(
17207 "GET / HTTP/1.1\r\n"
17208 "Host: www.example.org\r\n"
17209 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217210 };
17211 MockRead http_reads[] = {
17212 MockRead("HTTP/1.1 200 OK\r\n"),
17213 MockRead("Content-Length: 7\r\n\r\n"),
17214 MockRead("falafel"),
17215 MockRead(SYNCHRONOUS, OK),
17216 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117217 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217218 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17219
danakj1fd259a02016-04-16 03:17:0917220 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217221
17222 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
17223 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2917224 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5917225 http_stream_factory->PreconnectStreams(1, ssl_request);
Matt Menke9d5e2c92019-02-05 01:42:2317226 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217227
17228 // Start the HTTP request. Pool should stall.
17229 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617230 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017231 ASSERT_EQ(ERR_IO_PENDING,
17232 http_trans.Start(&http_request, http_callback.callback(),
17233 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117234 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217235
17236 // The SSL connection will automatically be closed once the connection is
17237 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0117238 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217239 std::string response_data;
bnc691fda62016-08-12 00:43:1617240 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217241 EXPECT_EQ("falafel", response_data);
17242
dcheng48459ac22014-08-26 00:46:4117243 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217244}
17245
bncd16676a2016-07-20 16:23:0117246TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917247 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217248 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917249 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217250 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417251
17252 HttpRequestInfo request;
17253 request.method = "POST";
17254 request.url = GURL("http://www.foo.com/");
17255 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017256 request.traffic_annotation =
17257 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417258
danakj1fd259a02016-04-16 03:17:0917259 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617260 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417261 // Send headers successfully, but get an error while sending the body.
17262 MockWrite data_writes[] = {
17263 MockWrite("POST / HTTP/1.1\r\n"
17264 "Host: www.foo.com\r\n"
17265 "Connection: keep-alive\r\n"
17266 "Content-Length: 3\r\n\r\n"),
17267 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17268 };
17269
17270 MockRead data_reads[] = {
17271 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17272 MockRead("hello world"),
17273 MockRead(SYNCHRONOUS, OK),
17274 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117275 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417276 session_deps_.socket_factory->AddSocketDataProvider(&data);
17277
17278 TestCompletionCallback callback;
17279
tfarina42834112016-09-22 13:38:2017280 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117281 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417282
17283 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117284 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417285
bnc691fda62016-08-12 00:43:1617286 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217287 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417288
wezca1070932016-05-26 20:30:5217289 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417290 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17291
17292 std::string response_data;
bnc691fda62016-08-12 00:43:1617293 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117294 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417295 EXPECT_EQ("hello world", response_data);
17296}
17297
17298// This test makes sure the retry logic doesn't trigger when reading an error
17299// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0117300TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417301 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0917302 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5417303 MockWrite data_writes[] = {
17304 MockWrite("GET / HTTP/1.1\r\n"
17305 "Host: www.foo.com\r\n"
17306 "Connection: keep-alive\r\n\r\n"),
17307 MockWrite("POST / HTTP/1.1\r\n"
17308 "Host: www.foo.com\r\n"
17309 "Connection: keep-alive\r\n"
17310 "Content-Length: 3\r\n\r\n"),
17311 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17312 };
17313
17314 MockRead data_reads[] = {
17315 MockRead("HTTP/1.1 200 Peachy\r\n"
17316 "Content-Length: 14\r\n\r\n"),
17317 MockRead("first response"),
17318 MockRead("HTTP/1.1 400 Not OK\r\n"
17319 "Content-Length: 15\r\n\r\n"),
17320 MockRead("second response"),
17321 MockRead(SYNCHRONOUS, OK),
17322 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117323 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417324 session_deps_.socket_factory->AddSocketDataProvider(&data);
17325
17326 TestCompletionCallback callback;
17327 HttpRequestInfo request1;
17328 request1.method = "GET";
17329 request1.url = GURL("http://www.foo.com/");
17330 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1017331 request1.traffic_annotation =
17332 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417333
bnc87dcefc2017-05-25 12:47:5817334 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1917335 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017336 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117337 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417338
17339 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117340 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417341
17342 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5217343 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5417344
wezca1070932016-05-26 20:30:5217345 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5417346 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
17347
17348 std::string response_data1;
17349 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0117350 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417351 EXPECT_EQ("first response", response_data1);
17352 // Delete the transaction to release the socket back into the socket pool.
17353 trans1.reset();
17354
danakj1fd259a02016-04-16 03:17:0917355 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217356 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917357 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217358 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417359
17360 HttpRequestInfo request2;
17361 request2.method = "POST";
17362 request2.url = GURL("http://www.foo.com/");
17363 request2.upload_data_stream = &upload_data_stream;
17364 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1017365 request2.traffic_annotation =
17366 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417367
bnc691fda62016-08-12 00:43:1617368 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017369 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117370 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417371
17372 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117373 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417374
bnc691fda62016-08-12 00:43:1617375 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5217376 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5417377
wezca1070932016-05-26 20:30:5217378 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5417379 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
17380
17381 std::string response_data2;
bnc691fda62016-08-12 00:43:1617382 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0117383 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417384 EXPECT_EQ("second response", response_data2);
17385}
17386
bncd16676a2016-07-20 16:23:0117387TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417388 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0917389 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217390 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917391 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217392 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417393
17394 HttpRequestInfo request;
17395 request.method = "POST";
17396 request.url = GURL("http://www.foo.com/");
17397 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017398 request.traffic_annotation =
17399 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417400
danakj1fd259a02016-04-16 03:17:0917401 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617402 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417403 // Send headers successfully, but get an error while sending the body.
17404 MockWrite data_writes[] = {
17405 MockWrite("POST / HTTP/1.1\r\n"
17406 "Host: www.foo.com\r\n"
17407 "Connection: keep-alive\r\n"
17408 "Content-Length: 3\r\n\r\n"
17409 "fo"),
17410 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17411 };
17412
17413 MockRead data_reads[] = {
17414 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17415 MockRead("hello world"),
17416 MockRead(SYNCHRONOUS, OK),
17417 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117418 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417419 session_deps_.socket_factory->AddSocketDataProvider(&data);
17420
17421 TestCompletionCallback callback;
17422
tfarina42834112016-09-22 13:38:2017423 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117424 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417425
17426 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117427 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417428
bnc691fda62016-08-12 00:43:1617429 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217430 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417431
wezca1070932016-05-26 20:30:5217432 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417433 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17434
17435 std::string response_data;
bnc691fda62016-08-12 00:43:1617436 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117437 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417438 EXPECT_EQ("hello world", response_data);
17439}
17440
17441// This tests the more common case than the previous test, where headers and
17442// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0117443TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0717444 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5417445
17446 HttpRequestInfo request;
17447 request.method = "POST";
17448 request.url = GURL("http://www.foo.com/");
17449 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017450 request.traffic_annotation =
17451 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417452
danakj1fd259a02016-04-16 03:17:0917453 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617454 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417455 // Send headers successfully, but get an error while sending the body.
17456 MockWrite data_writes[] = {
17457 MockWrite("POST / HTTP/1.1\r\n"
17458 "Host: www.foo.com\r\n"
17459 "Connection: keep-alive\r\n"
17460 "Transfer-Encoding: chunked\r\n\r\n"),
17461 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17462 };
17463
17464 MockRead data_reads[] = {
17465 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17466 MockRead("hello world"),
17467 MockRead(SYNCHRONOUS, OK),
17468 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117469 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417470 session_deps_.socket_factory->AddSocketDataProvider(&data);
17471
17472 TestCompletionCallback callback;
17473
tfarina42834112016-09-22 13:38:2017474 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417476 // Make sure the headers are sent before adding a chunk. This ensures that
17477 // they can't be merged with the body in a single send. Not currently
17478 // necessary since a chunked body is never merged with headers, but this makes
17479 // the test more future proof.
17480 base::RunLoop().RunUntilIdle();
17481
mmenkecbc2b712014-10-09 20:29:0717482 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5417483
17484 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117485 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417486
bnc691fda62016-08-12 00:43:1617487 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217488 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417489
wezca1070932016-05-26 20:30:5217490 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417491 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17492
17493 std::string response_data;
bnc691fda62016-08-12 00:43:1617494 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117495 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417496 EXPECT_EQ("hello world", response_data);
17497}
17498
bncd16676a2016-07-20 16:23:0117499TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917500 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217501 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917502 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217503 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417504
17505 HttpRequestInfo request;
17506 request.method = "POST";
17507 request.url = GURL("http://www.foo.com/");
17508 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017509 request.traffic_annotation =
17510 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417511
danakj1fd259a02016-04-16 03:17:0917512 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617513 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417514
17515 MockWrite data_writes[] = {
17516 MockWrite("POST / HTTP/1.1\r\n"
17517 "Host: www.foo.com\r\n"
17518 "Connection: keep-alive\r\n"
17519 "Content-Length: 3\r\n\r\n"),
17520 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17521 };
17522
17523 MockRead data_reads[] = {
17524 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17525 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17526 MockRead("hello world"),
17527 MockRead(SYNCHRONOUS, OK),
17528 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117529 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417530 session_deps_.socket_factory->AddSocketDataProvider(&data);
17531
17532 TestCompletionCallback callback;
17533
tfarina42834112016-09-22 13:38:2017534 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117535 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417536
17537 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117538 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417539
bnc691fda62016-08-12 00:43:1617540 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217541 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417542
wezca1070932016-05-26 20:30:5217543 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417544 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17545
17546 std::string response_data;
bnc691fda62016-08-12 00:43:1617547 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117548 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417549 EXPECT_EQ("hello world", response_data);
17550}
17551
bncd16676a2016-07-20 16:23:0117552TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917553 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217554 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917555 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217556 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417557
17558 HttpRequestInfo request;
17559 request.method = "POST";
17560 request.url = GURL("http://www.foo.com/");
17561 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017562 request.traffic_annotation =
17563 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417564
danakj1fd259a02016-04-16 03:17:0917565 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617566 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417567 // Send headers successfully, but get an error while sending the body.
17568 MockWrite data_writes[] = {
17569 MockWrite("POST / HTTP/1.1\r\n"
17570 "Host: www.foo.com\r\n"
17571 "Connection: keep-alive\r\n"
17572 "Content-Length: 3\r\n\r\n"),
17573 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17574 };
17575
17576 MockRead data_reads[] = {
17577 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17578 MockRead("hello world"),
17579 MockRead(SYNCHRONOUS, OK),
17580 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117581 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417582 session_deps_.socket_factory->AddSocketDataProvider(&data);
17583
17584 TestCompletionCallback callback;
17585
tfarina42834112016-09-22 13:38:2017586 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117587 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417588
17589 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117590 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417591}
17592
bncd16676a2016-07-20 16:23:0117593TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417594 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917595 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217596 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917597 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217598 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417599
17600 HttpRequestInfo request;
17601 request.method = "POST";
17602 request.url = GURL("http://www.foo.com/");
17603 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017604 request.traffic_annotation =
17605 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417606
danakj1fd259a02016-04-16 03:17:0917607 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617608 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417609 // Send headers successfully, but get an error while sending the body.
17610 MockWrite data_writes[] = {
17611 MockWrite("POST / HTTP/1.1\r\n"
17612 "Host: www.foo.com\r\n"
17613 "Connection: keep-alive\r\n"
17614 "Content-Length: 3\r\n\r\n"),
17615 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17616 };
17617
17618 MockRead data_reads[] = {
17619 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17620 MockRead("HTTP/1.0 302 Redirect\r\n"),
17621 MockRead("Location: http://somewhere-else.com/\r\n"),
17622 MockRead("Content-Length: 0\r\n\r\n"),
17623 MockRead(SYNCHRONOUS, OK),
17624 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117625 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417626 session_deps_.socket_factory->AddSocketDataProvider(&data);
17627
17628 TestCompletionCallback callback;
17629
tfarina42834112016-09-22 13:38:2017630 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417632
17633 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117634 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417635}
17636
bncd16676a2016-07-20 16:23:0117637TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917638 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217639 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917640 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217641 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417642
17643 HttpRequestInfo request;
17644 request.method = "POST";
17645 request.url = GURL("http://www.foo.com/");
17646 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017647 request.traffic_annotation =
17648 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417649
danakj1fd259a02016-04-16 03:17:0917650 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617651 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417652 // Send headers successfully, but get an error while sending the body.
17653 MockWrite data_writes[] = {
17654 MockWrite("POST / HTTP/1.1\r\n"
17655 "Host: www.foo.com\r\n"
17656 "Connection: keep-alive\r\n"
17657 "Content-Length: 3\r\n\r\n"),
17658 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17659 };
17660
17661 MockRead data_reads[] = {
17662 MockRead("HTTP 0.9 rocks!"),
17663 MockRead(SYNCHRONOUS, OK),
17664 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117665 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417666 session_deps_.socket_factory->AddSocketDataProvider(&data);
17667
17668 TestCompletionCallback callback;
17669
tfarina42834112016-09-22 13:38:2017670 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117671 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417672
17673 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117674 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417675}
17676
bncd16676a2016-07-20 16:23:0117677TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917678 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217679 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917680 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217681 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417682
17683 HttpRequestInfo request;
17684 request.method = "POST";
17685 request.url = GURL("http://www.foo.com/");
17686 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017687 request.traffic_annotation =
17688 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417689
danakj1fd259a02016-04-16 03:17:0917690 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617691 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417692 // Send headers successfully, but get an error while sending the body.
17693 MockWrite data_writes[] = {
17694 MockWrite("POST / HTTP/1.1\r\n"
17695 "Host: www.foo.com\r\n"
17696 "Connection: keep-alive\r\n"
17697 "Content-Length: 3\r\n\r\n"),
17698 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17699 };
17700
17701 MockRead data_reads[] = {
17702 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17703 MockRead(SYNCHRONOUS, OK),
17704 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117705 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417706 session_deps_.socket_factory->AddSocketDataProvider(&data);
17707
17708 TestCompletionCallback callback;
17709
tfarina42834112016-09-22 13:38:2017710 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417712
17713 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117714 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417715}
17716
Bence Békydca6bd92018-01-30 13:43:0617717#if BUILDFLAG(ENABLE_WEBSOCKETS)
17718
17719namespace {
17720
17721void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17722 headers->SetHeader("Connection", "Upgrade");
17723 headers->SetHeader("Upgrade", "websocket");
17724 headers->SetHeader("Origin", "http://www.example.org");
17725 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617726}
17727
17728} // namespace
17729
17730TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Béky2fcf4fa2018-04-06 20:06:0117731 for (bool secure : {true, false}) {
17732 MockWrite data_writes[] = {
17733 MockWrite("GET / HTTP/1.1\r\n"
17734 "Host: www.example.org\r\n"
17735 "Connection: Upgrade\r\n"
17736 "Upgrade: websocket\r\n"
17737 "Origin: http://www.example.org\r\n"
17738 "Sec-WebSocket-Version: 13\r\n"
17739 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17740 "Sec-WebSocket-Extensions: permessage-deflate; "
17741 "client_max_window_bits\r\n\r\n")};
17742
17743 MockRead data_reads[] = {
17744 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17745 "Upgrade: websocket\r\n"
17746 "Connection: Upgrade\r\n"
17747 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
17748
Ryan Sleevib8d7ea02018-05-07 20:01:0117749 StaticSocketDataProvider data(data_reads, data_writes);
Bence Béky2fcf4fa2018-04-06 20:06:0117750 session_deps_.socket_factory->AddSocketDataProvider(&data);
17751 SSLSocketDataProvider ssl(ASYNC, OK);
17752 if (secure)
17753 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
Bence Békydca6bd92018-01-30 13:43:0617754
17755 HttpRequestInfo request;
17756 request.method = "GET";
Bence Béky2fcf4fa2018-04-06 20:06:0117757 request.url =
17758 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17759 AddWebSocketHeaders(&request.extra_headers);
Ramin Halavatib5e433e62018-02-07 07:41:1017760 request.traffic_annotation =
17761 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617762
Bence Béky2fcf4fa2018-04-06 20:06:0117763 TestWebSocketHandshakeStreamCreateHelper
17764 websocket_handshake_stream_create_helper;
Bence Béky8d1c6052018-02-07 12:48:1517765
Bence Béky2fcf4fa2018-04-06 20:06:0117766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Bence Békydca6bd92018-01-30 13:43:0617767 HttpNetworkTransaction trans(LOW, session.get());
17768 trans.SetWebSocketHandshakeStreamCreateHelper(
Bence Béky2fcf4fa2018-04-06 20:06:0117769 &websocket_handshake_stream_create_helper);
Bence Békydca6bd92018-01-30 13:43:0617770
17771 TestCompletionCallback callback;
Bence Béky2fcf4fa2018-04-06 20:06:0117772 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17773 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Bence Békydca6bd92018-01-30 13:43:0617774
Bence Béky2fcf4fa2018-04-06 20:06:0117775 const HttpStreamRequest* stream_request = trans.stream_request_.get();
17776 ASSERT_TRUE(stream_request);
17777 EXPECT_EQ(&websocket_handshake_stream_create_helper,
17778 stream_request->websocket_handshake_stream_create_helper());
17779
17780 rv = callback.WaitForResult();
17781 EXPECT_THAT(rv, IsOk());
17782
17783 EXPECT_TRUE(data.AllReadDataConsumed());
17784 EXPECT_TRUE(data.AllWriteDataConsumed());
Bence Békydca6bd92018-01-30 13:43:0617785 }
17786}
17787
Adam Rice425cf122015-01-19 06:18:2417788// Verify that proxy headers are not sent to the destination server when
17789// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117790TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417791 HttpRequestInfo request;
17792 request.method = "GET";
bncce36dca22015-04-21 22:11:2317793 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017794 request.traffic_annotation =
17795 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417796 AddWebSocketHeaders(&request.extra_headers);
17797
17798 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917799 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917800 ProxyResolutionService::CreateFixedFromPacResult(
17801 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417802
danakj1fd259a02016-04-16 03:17:0917803 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417804
17805 // Since a proxy is configured, try to establish a tunnel.
17806 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717807 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17808 "Host: www.example.org:443\r\n"
17809 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417810
17811 // After calling trans->RestartWithAuth(), this is the request we should
17812 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717813 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17814 "Host: www.example.org:443\r\n"
17815 "Proxy-Connection: keep-alive\r\n"
17816 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417817
rsleevidb16bb02015-11-12 23:47:1717818 MockWrite("GET / HTTP/1.1\r\n"
17819 "Host: www.example.org\r\n"
17820 "Connection: Upgrade\r\n"
17821 "Upgrade: websocket\r\n"
17822 "Origin: http://www.example.org\r\n"
17823 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517824 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17825 "Sec-WebSocket-Extensions: permessage-deflate; "
17826 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417827
17828 // The proxy responds to the connect with a 407, using a persistent
17829 // connection.
17830 MockRead data_reads[] = {
17831 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517832 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17833 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17834 "Content-Length: 0\r\n"
17835 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417836
17837 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17838
Bence Béky8d1c6052018-02-07 12:48:1517839 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17840 "Upgrade: websocket\r\n"
17841 "Connection: Upgrade\r\n"
17842 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417843
Ryan Sleevib8d7ea02018-05-07 20:01:0117844 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417845 session_deps_.socket_factory->AddSocketDataProvider(&data);
17846 SSLSocketDataProvider ssl(ASYNC, OK);
17847 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17848
Bence Béky8d1c6052018-02-07 12:48:1517849 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17850
bnc87dcefc2017-05-25 12:47:5817851 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917852 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417853 trans->SetWebSocketHandshakeStreamCreateHelper(
17854 &websocket_stream_create_helper);
17855
17856 {
17857 TestCompletionCallback callback;
17858
tfarina42834112016-09-22 13:38:2017859 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117860 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417861
17862 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117863 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417864 }
17865
17866 const HttpResponseInfo* response = trans->GetResponseInfo();
17867 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217868 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417869 EXPECT_EQ(407, response->headers->response_code());
17870
17871 {
17872 TestCompletionCallback callback;
17873
17874 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17875 callback.callback());
robpercival214763f2016-07-01 23:27:0117876 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417877
17878 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117879 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417880 }
17881
17882 response = trans->GetResponseInfo();
17883 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217884 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417885
17886 EXPECT_EQ(101, response->headers->response_code());
17887
17888 trans.reset();
17889 session->CloseAllConnections();
17890}
17891
17892// Verify that proxy headers are not sent to the destination server when
17893// establishing a tunnel for an insecure WebSocket connection.
17894// This requires the authentication info to be injected into the auth cache
17895// due to crbug.com/395064
17896// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117897TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417898 HttpRequestInfo request;
17899 request.method = "GET";
bncce36dca22015-04-21 22:11:2317900 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017901 request.traffic_annotation =
17902 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417903 AddWebSocketHeaders(&request.extra_headers);
17904
17905 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917906 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917907 ProxyResolutionService::CreateFixedFromPacResult(
17908 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417909
danakj1fd259a02016-04-16 03:17:0917910 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417911
17912 MockWrite data_writes[] = {
17913 // Try to establish a tunnel for the WebSocket connection, with
17914 // credentials. Because WebSockets have a separate set of socket pools,
17915 // they cannot and will not use the same TCP/IP connection as the
17916 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517917 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17918 "Host: www.example.org:80\r\n"
17919 "Proxy-Connection: keep-alive\r\n"
17920 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417921
Bence Béky8d1c6052018-02-07 12:48:1517922 MockWrite("GET / HTTP/1.1\r\n"
17923 "Host: www.example.org\r\n"
17924 "Connection: Upgrade\r\n"
17925 "Upgrade: websocket\r\n"
17926 "Origin: http://www.example.org\r\n"
17927 "Sec-WebSocket-Version: 13\r\n"
17928 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17929 "Sec-WebSocket-Extensions: permessage-deflate; "
17930 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417931
17932 MockRead data_reads[] = {
17933 // HTTP CONNECT with credentials.
17934 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17935
17936 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517937 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17938 "Upgrade: websocket\r\n"
17939 "Connection: Upgrade\r\n"
17940 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417941
Ryan Sleevib8d7ea02018-05-07 20:01:0117942 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417943 session_deps_.socket_factory->AddSocketDataProvider(&data);
17944
17945 session->http_auth_cache()->Add(
17946 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17947 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17948
Bence Béky8d1c6052018-02-07 12:48:1517949 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17950
bnc87dcefc2017-05-25 12:47:5817951 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917952 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417953 trans->SetWebSocketHandshakeStreamCreateHelper(
17954 &websocket_stream_create_helper);
17955
17956 TestCompletionCallback callback;
17957
tfarina42834112016-09-22 13:38:2017958 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417960
17961 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117962 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417963
17964 const HttpResponseInfo* response = trans->GetResponseInfo();
17965 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217966 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417967
17968 EXPECT_EQ(101, response->headers->response_code());
17969
17970 trans.reset();
17971 session->CloseAllConnections();
17972}
17973
Matt Menke1d6093e32019-03-22 17:33:4317974// WebSockets over QUIC is not supported, including over QUIC proxies.
17975TEST_F(HttpNetworkTransactionTest, WebSocketNotSentOverQuicProxy) {
17976 for (bool secure : {true, false}) {
17977 SCOPED_TRACE(secure);
17978 session_deps_.proxy_resolution_service =
17979 ProxyResolutionService::CreateFixedFromPacResult(
17980 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
17981 session_deps_.enable_quic = true;
17982
17983 HttpRequestInfo request;
17984 request.url =
17985 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17986 AddWebSocketHeaders(&request.extra_headers);
17987 request.traffic_annotation =
17988 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17989
17990 TestWebSocketHandshakeStreamCreateHelper
17991 websocket_handshake_stream_create_helper;
17992
17993 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17994 HttpNetworkTransaction trans(LOW, session.get());
17995 trans.SetWebSocketHandshakeStreamCreateHelper(
17996 &websocket_handshake_stream_create_helper);
17997
17998 TestCompletionCallback callback;
17999 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18000 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18001
18002 rv = callback.WaitForResult();
18003 EXPECT_THAT(rv, IsError(ERR_NO_SUPPORTED_PROXIES));
18004 }
18005}
18006
Bence Békydca6bd92018-01-30 13:43:0618007#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
18008
bncd16676a2016-07-20 16:23:0118009TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0918010 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2218011 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1918012 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2218013 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2218014
18015 HttpRequestInfo request;
18016 request.method = "POST";
18017 request.url = GURL("http://www.foo.com/");
18018 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1018019 request.traffic_annotation =
18020 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218021
danakj1fd259a02016-04-16 03:17:0918022 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618023 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218024 MockWrite data_writes[] = {
18025 MockWrite("POST / HTTP/1.1\r\n"
18026 "Host: www.foo.com\r\n"
18027 "Connection: keep-alive\r\n"
18028 "Content-Length: 3\r\n\r\n"),
18029 MockWrite("foo"),
18030 };
18031
18032 MockRead data_reads[] = {
18033 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18034 MockRead(SYNCHRONOUS, OK),
18035 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118036 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218037 session_deps_.socket_factory->AddSocketDataProvider(&data);
18038
18039 TestCompletionCallback callback;
18040
18041 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018042 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0118043 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218044
18045 std::string response_data;
bnc691fda62016-08-12 00:43:1618046 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218047
Ryan Sleevib8d7ea02018-05-07 20:01:0118048 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18049 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218050}
18051
bncd16676a2016-07-20 16:23:0118052TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0918053 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2218054 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1918055 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2218056 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2218057
18058 HttpRequestInfo request;
18059 request.method = "POST";
18060 request.url = GURL("http://www.foo.com/");
18061 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1018062 request.traffic_annotation =
18063 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218064
danakj1fd259a02016-04-16 03:17:0918065 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618066 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218067 MockWrite data_writes[] = {
18068 MockWrite("POST / HTTP/1.1\r\n"
18069 "Host: www.foo.com\r\n"
18070 "Connection: keep-alive\r\n"
18071 "Content-Length: 3\r\n\r\n"),
18072 MockWrite("foo"),
18073 };
18074
18075 MockRead data_reads[] = {
18076 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
18077 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18078 MockRead(SYNCHRONOUS, OK),
18079 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118080 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218081 session_deps_.socket_factory->AddSocketDataProvider(&data);
18082
18083 TestCompletionCallback callback;
18084
18085 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018086 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0118087 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218088
18089 std::string response_data;
bnc691fda62016-08-12 00:43:1618090 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218091
Ryan Sleevib8d7ea02018-05-07 20:01:0118092 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18093 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218094}
18095
bncd16676a2016-07-20 16:23:0118096TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2218097 ChunkedUploadDataStream upload_data_stream(0);
18098
18099 HttpRequestInfo request;
18100 request.method = "POST";
18101 request.url = GURL("http://www.foo.com/");
18102 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1018103 request.traffic_annotation =
18104 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218105
danakj1fd259a02016-04-16 03:17:0918106 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618107 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218108 // Send headers successfully, but get an error while sending the body.
18109 MockWrite data_writes[] = {
18110 MockWrite("POST / HTTP/1.1\r\n"
18111 "Host: www.foo.com\r\n"
18112 "Connection: keep-alive\r\n"
18113 "Transfer-Encoding: chunked\r\n\r\n"),
18114 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
18115 };
18116
18117 MockRead data_reads[] = {
18118 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18119 MockRead(SYNCHRONOUS, OK),
18120 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118121 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218122 session_deps_.socket_factory->AddSocketDataProvider(&data);
18123
18124 TestCompletionCallback callback;
18125
18126 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018127 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2218128
18129 base::RunLoop().RunUntilIdle();
18130 upload_data_stream.AppendData("f", 1, false);
18131
18132 base::RunLoop().RunUntilIdle();
18133 upload_data_stream.AppendData("oo", 2, true);
18134
robpercival214763f2016-07-01 23:27:0118135 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218136
18137 std::string response_data;
bnc691fda62016-08-12 00:43:1618138 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218139
Ryan Sleevib8d7ea02018-05-07 20:01:0118140 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18141 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218142}
18143
eustasc7d27da2017-04-06 10:33:2018144void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
18145 const std::string& accept_encoding,
18146 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0318147 const std::string& location,
eustasc7d27da2017-04-06 10:33:2018148 bool should_match) {
18149 HttpRequestInfo request;
18150 request.method = "GET";
18151 request.url = GURL("http://www.foo.com/");
18152 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
18153 accept_encoding);
Ramin Halavatib5e433e62018-02-07 07:41:1018154 request.traffic_annotation =
18155 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2018156
18157 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
18158 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18159 // Send headers successfully, but get an error while sending the body.
18160 MockWrite data_writes[] = {
18161 MockWrite("GET / HTTP/1.1\r\n"
18162 "Host: www.foo.com\r\n"
18163 "Connection: keep-alive\r\n"
18164 "Accept-Encoding: "),
18165 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
18166 };
18167
sky50576f32017-05-01 19:28:0318168 std::string response_code = "200 OK";
18169 std::string extra;
18170 if (!location.empty()) {
18171 response_code = "301 Redirect\r\nLocation: ";
18172 response_code.append(location);
18173 }
18174
eustasc7d27da2017-04-06 10:33:2018175 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0318176 MockRead("HTTP/1.0 "),
18177 MockRead(response_code.data()),
18178 MockRead("\r\nContent-Encoding: "),
18179 MockRead(content_encoding.data()),
18180 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2018181 MockRead(SYNCHRONOUS, OK),
18182 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118183 StaticSocketDataProvider data(data_reads, data_writes);
eustasc7d27da2017-04-06 10:33:2018184 session_deps->socket_factory->AddSocketDataProvider(&data);
18185
18186 TestCompletionCallback callback;
18187
18188 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18189 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18190
18191 rv = callback.WaitForResult();
18192 if (should_match) {
18193 EXPECT_THAT(rv, IsOk());
18194 } else {
18195 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
18196 }
18197}
18198
18199TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0318200 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2018201}
18202
18203TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0318204 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
18205 true);
eustasc7d27da2017-04-06 10:33:2018206}
18207
18208TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
18209 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0318210 "", false);
18211}
18212
18213TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
18214 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
18215 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2018216}
18217
xunjieli96f2a402017-06-05 17:24:2718218TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
18219 ProxyConfig proxy_config;
18220 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18221 proxy_config.set_pac_mandatory(true);
18222 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918223 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918224 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18225 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0418226 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2718227
18228 HttpRequestInfo request;
18229 request.method = "GET";
18230 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018231 request.traffic_annotation =
18232 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718233
18234 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18235 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18236
18237 TestCompletionCallback callback;
18238
18239 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18240 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18241 EXPECT_THAT(callback.WaitForResult(),
18242 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18243}
18244
18245TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
18246 ProxyConfig proxy_config;
18247 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18248 proxy_config.set_pac_mandatory(true);
18249 MockAsyncProxyResolverFactory* proxy_resolver_factory =
18250 new MockAsyncProxyResolverFactory(false);
18251 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918252 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918253 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18254 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5918255 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2718256 HttpRequestInfo request;
18257 request.method = "GET";
18258 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018259 request.traffic_annotation =
18260 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718261
18262 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18263 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18264
18265 TestCompletionCallback callback;
18266 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18267 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18268
18269 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
18270 ERR_FAILED, &resolver);
18271 EXPECT_THAT(callback.WaitForResult(),
18272 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18273}
18274
18275TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5918276 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4918277 ProxyResolutionService::CreateFixedFromPacResult(
18278 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718279 session_deps_.enable_quic = false;
18280 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18281
18282 HttpRequestInfo request;
18283 request.method = "GET";
18284 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018285 request.traffic_annotation =
18286 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718287
18288 TestCompletionCallback callback;
18289 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18290 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18291 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18292
18293 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18294}
18295
Douglas Creager3cb042052018-11-06 23:08:5218296//-----------------------------------------------------------------------------
Douglas Creager134b52e2018-11-09 18:00:1418297// Reporting tests
18298
18299#if BUILDFLAG(ENABLE_REPORTING)
18300class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest {
18301 protected:
18302 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618303 HttpNetworkTransactionTest::SetUp();
Douglas Creager134b52e2018-11-09 18:00:1418304 auto test_reporting_context = std::make_unique<TestReportingContext>(
18305 &clock_, &tick_clock_, ReportingPolicy());
18306 test_reporting_context_ = test_reporting_context.get();
18307 session_deps_.reporting_service =
18308 ReportingService::CreateForTesting(std::move(test_reporting_context));
18309 }
18310
18311 TestReportingContext* reporting_context() const {
18312 return test_reporting_context_;
18313 }
18314
18315 void clear_reporting_service() {
18316 session_deps_.reporting_service.reset();
18317 test_reporting_context_ = nullptr;
18318 }
18319
18320 // Makes an HTTPS request that should install a valid Reporting policy.
Lily Chenfec60d92019-01-24 01:16:4218321 void RequestPolicy(CertStatus cert_status = 0) {
18322 HttpRequestInfo request;
18323 request.method = "GET";
18324 request.url = GURL(url_);
18325 request.traffic_annotation =
18326 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18327
Lily Chend3930e72019-03-01 19:31:1118328 MockWrite data_writes[] = {
18329 MockWrite("GET / HTTP/1.1\r\n"
18330 "Host: www.example.org\r\n"
18331 "Connection: keep-alive\r\n\r\n"),
18332 };
Douglas Creager134b52e2018-11-09 18:00:1418333 MockRead data_reads[] = {
18334 MockRead("HTTP/1.0 200 OK\r\n"),
18335 MockRead("Report-To: {\"group\": \"nel\", \"max_age\": 86400, "
18336 "\"endpoints\": [{\"url\": "
18337 "\"https://www.example.org/upload/\"}]}\r\n"),
18338 MockRead("\r\n"),
18339 MockRead("hello world"),
18340 MockRead(SYNCHRONOUS, OK),
18341 };
Douglas Creager134b52e2018-11-09 18:00:1418342
Lily Chenfec60d92019-01-24 01:16:4218343 StaticSocketDataProvider reads(data_reads, data_writes);
18344 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager134b52e2018-11-09 18:00:1418345
18346 SSLSocketDataProvider ssl(ASYNC, OK);
18347 if (request.url.SchemeIsCryptographic()) {
18348 ssl.ssl_info.cert =
18349 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18350 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218351 ssl.ssl_info.cert_status = cert_status;
Douglas Creager134b52e2018-11-09 18:00:1418352 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18353 }
18354
Douglas Creager134b52e2018-11-09 18:00:1418355 TestCompletionCallback callback;
18356 auto session = CreateSession(&session_deps_);
18357 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18358 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
Lily Chenfec60d92019-01-24 01:16:4218359 EXPECT_THAT(callback.GetResult(rv), IsOk());
Douglas Creager134b52e2018-11-09 18:00:1418360 }
18361
18362 protected:
18363 std::string url_ = "https://www.example.org/";
Douglas Creager134b52e2018-11-09 18:00:1418364
18365 private:
18366 TestReportingContext* test_reporting_context_;
18367};
18368
18369TEST_F(HttpNetworkTransactionReportingTest,
18370 DontProcessReportToHeaderNoService) {
18371 base::HistogramTester histograms;
18372 clear_reporting_service();
18373 RequestPolicy();
18374 histograms.ExpectBucketCount(
18375 ReportingHeaderParser::kHeaderOutcomeHistogram,
18376 ReportingHeaderParser::HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE, 1);
18377}
18378
18379TEST_F(HttpNetworkTransactionReportingTest, DontProcessReportToHeaderHttp) {
18380 base::HistogramTester histograms;
18381 url_ = "http://www.example.org/";
18382 RequestPolicy();
18383 histograms.ExpectBucketCount(
18384 ReportingHeaderParser::kHeaderOutcomeHistogram,
18385 ReportingHeaderParser::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18386}
18387
18388TEST_F(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
18389 RequestPolicy();
18390 std::vector<const ReportingClient*> clients;
18391 reporting_context()->cache()->GetClients(&clients);
18392 ASSERT_EQ(1u, clients.size());
18393 const auto* client = clients[0];
18394 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18395 client->origin);
18396 EXPECT_EQ(GURL("https://www.example.org/upload/"), client->endpoint);
18397 EXPECT_EQ("nel", client->group);
18398}
18399
18400TEST_F(HttpNetworkTransactionReportingTest,
18401 DontProcessReportToHeaderInvalidHttps) {
18402 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218403 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18404 RequestPolicy(cert_status);
Douglas Creager134b52e2018-11-09 18:00:1418405 histograms.ExpectBucketCount(
18406 ReportingHeaderParser::kHeaderOutcomeHistogram,
18407 ReportingHeaderParser::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR, 1);
18408}
18409#endif // BUILDFLAG(ENABLE_REPORTING)
18410
18411//-----------------------------------------------------------------------------
Douglas Creager3cb042052018-11-06 23:08:5218412// Network Error Logging tests
18413
18414#if BUILDFLAG(ENABLE_REPORTING)
Lily Chenfec60d92019-01-24 01:16:4218415namespace {
18416
18417const char kUserAgent[] = "Mozilla/1.0";
18418const char kReferrer[] = "https://www.referrer.org/";
18419
18420} // namespace
18421
Douglas Creager3cb042052018-11-06 23:08:5218422class HttpNetworkTransactionNetworkErrorLoggingTest
18423 : public HttpNetworkTransactionTest {
18424 protected:
18425 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618426 HttpNetworkTransactionTest::SetUp();
Douglas Creager3cb042052018-11-06 23:08:5218427 auto network_error_logging_service =
18428 std::make_unique<TestNetworkErrorLoggingService>();
18429 test_network_error_logging_service_ = network_error_logging_service.get();
18430 session_deps_.network_error_logging_service =
18431 std::move(network_error_logging_service);
Lily Chenfec60d92019-01-24 01:16:4218432
18433 extra_headers_.SetHeader("User-Agent", kUserAgent);
18434 extra_headers_.SetHeader("Referer", kReferrer);
18435
18436 request_.method = "GET";
18437 request_.url = GURL(url_);
18438 request_.extra_headers = extra_headers_;
18439 request_.reporting_upload_depth = reporting_upload_depth_;
18440 request_.traffic_annotation =
18441 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Douglas Creager3cb042052018-11-06 23:08:5218442 }
18443
18444 TestNetworkErrorLoggingService* network_error_logging_service() const {
18445 return test_network_error_logging_service_;
18446 }
18447
18448 void clear_network_error_logging_service() {
18449 session_deps_.network_error_logging_service.reset();
18450 test_network_error_logging_service_ = nullptr;
18451 }
18452
18453 // Makes an HTTPS request that should install a valid NEL policy.
Lily Chenfec60d92019-01-24 01:16:4218454 void RequestPolicy(CertStatus cert_status = 0) {
Douglas Creageref5eecdc2018-11-09 20:50:3618455 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318456 MockWrite data_writes[] = {
18457 MockWrite("GET / HTTP/1.1\r\n"
18458 "Host: www.example.org\r\n"
18459 "Connection: keep-alive\r\n"),
18460 MockWrite(ASYNC, extra_header_string.data(),
18461 extra_header_string.size()),
18462 };
Lily Chend3930e72019-03-01 19:31:1118463 MockRead data_reads[] = {
18464 MockRead("HTTP/1.0 200 OK\r\n"),
18465 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18466 MockRead("\r\n"),
18467 MockRead("hello world"),
18468 MockRead(SYNCHRONOUS, OK),
18469 };
Douglas Creager3cb042052018-11-06 23:08:5218470
Lily Chenfec60d92019-01-24 01:16:4218471 StaticSocketDataProvider reads(data_reads, data_writes);
18472 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager3cb042052018-11-06 23:08:5218473
18474 SSLSocketDataProvider ssl(ASYNC, OK);
Lily Chenfec60d92019-01-24 01:16:4218475 if (request_.url.SchemeIsCryptographic()) {
Douglas Creager3cb042052018-11-06 23:08:5218476 ssl.ssl_info.cert =
18477 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18478 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218479 ssl.ssl_info.cert_status = cert_status;
Douglas Creager3cb042052018-11-06 23:08:5218480 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18481 }
18482
Douglas Creager3cb042052018-11-06 23:08:5218483 TestCompletionCallback callback;
18484 auto session = CreateSession(&session_deps_);
18485 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
Lily Chenfec60d92019-01-24 01:16:4218486 int rv = trans.Start(&request_, callback.callback(), NetLogWithSource());
18487 EXPECT_THAT(callback.GetResult(rv), IsOk());
18488
18489 std::string response_data;
18490 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
18491 EXPECT_EQ("hello world", response_data);
18492 }
18493
18494 void CheckReport(size_t index,
18495 int status_code,
18496 int error_type,
18497 IPAddress server_ip = IPAddress::IPv4Localhost()) {
18498 ASSERT_LT(index, network_error_logging_service()->errors().size());
18499
18500 const NetworkErrorLoggingService::RequestDetails& error =
18501 network_error_logging_service()->errors()[index];
18502 EXPECT_EQ(url_, error.uri);
18503 EXPECT_EQ(kReferrer, error.referrer);
18504 EXPECT_EQ(kUserAgent, error.user_agent);
18505 EXPECT_EQ(server_ip, error.server_ip);
18506 EXPECT_EQ("http/1.1", error.protocol);
18507 EXPECT_EQ("GET", error.method);
18508 EXPECT_EQ(status_code, error.status_code);
18509 EXPECT_EQ(error_type, error.type);
18510 EXPECT_EQ(0, error.reporting_upload_depth);
Douglas Creager3cb042052018-11-06 23:08:5218511 }
18512
18513 protected:
18514 std::string url_ = "https://www.example.org/";
18515 CertStatus cert_status_ = 0;
Lily Chenfec60d92019-01-24 01:16:4218516 HttpRequestInfo request_;
Douglas Creageref5eecdc2018-11-09 20:50:3618517 HttpRequestHeaders extra_headers_;
18518 int reporting_upload_depth_ = 0;
Douglas Creager3cb042052018-11-06 23:08:5218519
18520 private:
18521 TestNetworkErrorLoggingService* test_network_error_logging_service_;
18522};
18523
18524TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18525 DontProcessNelHeaderNoService) {
18526 base::HistogramTester histograms;
18527 clear_network_error_logging_service();
18528 RequestPolicy();
18529 histograms.ExpectBucketCount(
18530 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18531 NetworkErrorLoggingService::HeaderOutcome::
18532 DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE,
18533 1);
18534}
18535
18536TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18537 DontProcessNelHeaderHttp) {
18538 base::HistogramTester histograms;
18539 url_ = "http://www.example.org/";
Lily Chenfec60d92019-01-24 01:16:4218540 request_.url = GURL(url_);
Douglas Creager3cb042052018-11-06 23:08:5218541 RequestPolicy();
18542 histograms.ExpectBucketCount(
18543 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18544 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18545}
18546
Lily Chen90ae93cc2019-02-14 01:15:3918547// Don't set NEL policies received on a proxied connection.
18548TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18549 DontProcessNelHeaderProxy) {
18550 session_deps_.proxy_resolution_service =
18551 ProxyResolutionService::CreateFixedFromPacResult(
18552 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
18553 BoundTestNetLog log;
18554 session_deps_.net_log = log.bound().net_log();
18555 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18556
18557 HttpRequestInfo request;
18558 request.method = "GET";
18559 request.url = GURL("https://www.example.org/");
18560 request.traffic_annotation =
18561 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18562
18563 // Since we have proxy, should try to establish tunnel.
18564 MockWrite data_writes1[] = {
18565 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
18566 "Host: www.example.org:443\r\n"
18567 "Proxy-Connection: keep-alive\r\n\r\n"),
18568
18569 MockWrite("GET / HTTP/1.1\r\n"
18570 "Host: www.example.org\r\n"
18571 "Connection: keep-alive\r\n\r\n"),
18572 };
18573
18574 MockRead data_reads1[] = {
18575 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
18576
18577 MockRead("HTTP/1.1 200 OK\r\n"),
18578 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18579 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18580 MockRead("Content-Length: 100\r\n\r\n"),
18581 MockRead(SYNCHRONOUS, OK),
18582 };
18583
18584 StaticSocketDataProvider data1(data_reads1, data_writes1);
18585 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18586 SSLSocketDataProvider ssl(ASYNC, OK);
18587 ssl.ssl_info.cert =
18588 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18589 ASSERT_TRUE(ssl.ssl_info.cert);
18590 ssl.ssl_info.cert_status = 0;
18591 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18592
18593 TestCompletionCallback callback1;
18594 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18595
18596 int rv = trans.Start(&request, callback1.callback(), log.bound());
18597 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18598
18599 rv = callback1.WaitForResult();
18600 EXPECT_THAT(rv, IsOk());
18601
18602 const HttpResponseInfo* response = trans.GetResponseInfo();
18603 ASSERT_TRUE(response);
18604 EXPECT_EQ(200, response->headers->response_code());
18605 EXPECT_TRUE(response->was_fetched_via_proxy);
18606
18607 // No NEL header was set.
18608 EXPECT_EQ(0u, network_error_logging_service()->headers().size());
18609}
18610
Douglas Creager3cb042052018-11-06 23:08:5218611TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) {
18612 RequestPolicy();
18613 ASSERT_EQ(1u, network_error_logging_service()->headers().size());
18614 const auto& header = network_error_logging_service()->headers()[0];
18615 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18616 header.origin);
18617 EXPECT_EQ(IPAddress::IPv4Localhost(), header.received_ip_address);
18618 EXPECT_EQ("{\"report_to\": \"nel\", \"max_age\": 86400}", header.value);
18619}
18620
18621TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18622 DontProcessNelHeaderInvalidHttps) {
18623 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218624 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18625 RequestPolicy(cert_status);
Douglas Creager3cb042052018-11-06 23:08:5218626 histograms.ExpectBucketCount(
18627 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18628 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR,
18629 1);
18630}
Douglas Creageref5eecdc2018-11-09 20:50:3618631
Lily Chenfec60d92019-01-24 01:16:4218632TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportSuccess) {
Douglas Creageref5eecdc2018-11-09 20:50:3618633 RequestPolicy();
18634 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4218635 CheckReport(0 /* index */, 200 /* status_code */, OK);
18636}
18637
18638TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18639 CreateReportErrorAfterStart) {
18640 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18641 auto trans =
18642 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18643
18644 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
18645 StaticSocketDataProvider data;
18646 data.set_connect_data(mock_connect);
18647 session_deps_.socket_factory->AddSocketDataProvider(&data);
18648
18649 TestCompletionCallback callback;
18650
18651 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18652 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18653
18654 trans.reset();
18655
18656 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18657 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18658 IPAddress() /* server_ip */);
18659}
18660
18661// Same as above except the error is ASYNC
18662TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18663 CreateReportErrorAfterStartAsync) {
18664 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18665 auto trans =
18666 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18667
18668 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
18669 StaticSocketDataProvider data;
18670 data.set_connect_data(mock_connect);
18671 session_deps_.socket_factory->AddSocketDataProvider(&data);
18672
18673 TestCompletionCallback callback;
18674
18675 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18676 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18677
18678 trans.reset();
18679
18680 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18681 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18682 IPAddress() /* server_ip */);
18683}
18684
18685TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18686 CreateReportReadBodyError) {
18687 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318688 MockWrite data_writes[] = {
18689 MockWrite("GET / HTTP/1.1\r\n"
18690 "Host: www.example.org\r\n"
18691 "Connection: keep-alive\r\n"),
18692 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18693 };
Lily Chend3930e72019-03-01 19:31:1118694 MockRead data_reads[] = {
18695 MockRead("HTTP/1.0 200 OK\r\n"),
18696 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18697 MockRead("hello world"),
18698 MockRead(SYNCHRONOUS, OK),
18699 };
Lily Chenfec60d92019-01-24 01:16:4218700
18701 StaticSocketDataProvider reads(data_reads, data_writes);
18702 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18703
18704 SSLSocketDataProvider ssl(ASYNC, OK);
18705 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18706
18707 // Log start time
18708 base::TimeTicks start_time = base::TimeTicks::Now();
18709
18710 TestCompletionCallback callback;
18711 auto session = CreateSession(&session_deps_);
18712 auto trans =
18713 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18714 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18715 EXPECT_THAT(callback.GetResult(rv), IsOk());
18716
18717 const HttpResponseInfo* response = trans->GetResponseInfo();
18718 ASSERT_TRUE(response);
18719
18720 EXPECT_TRUE(response->headers);
18721 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18722
18723 std::string response_data;
18724 rv = ReadTransaction(trans.get(), &response_data);
18725 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18726
18727 trans.reset();
18728
18729 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18730
18731 CheckReport(0 /* index */, 200 /* status_code */,
18732 ERR_CONTENT_LENGTH_MISMATCH);
18733 const NetworkErrorLoggingService::RequestDetails& error =
18734 network_error_logging_service()->errors()[0];
18735 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18736}
18737
18738// Same as above except the final read is ASYNC.
18739TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18740 CreateReportReadBodyErrorAsync) {
18741 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318742 MockWrite data_writes[] = {
18743 MockWrite("GET / HTTP/1.1\r\n"
18744 "Host: www.example.org\r\n"
18745 "Connection: keep-alive\r\n"),
18746 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18747 };
Lily Chend3930e72019-03-01 19:31:1118748 MockRead data_reads[] = {
18749 MockRead("HTTP/1.0 200 OK\r\n"),
18750 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18751 MockRead("hello world"),
18752 MockRead(ASYNC, OK),
18753 };
Lily Chenfec60d92019-01-24 01:16:4218754
18755 StaticSocketDataProvider reads(data_reads, data_writes);
18756 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18757
18758 SSLSocketDataProvider ssl(ASYNC, OK);
18759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18760
18761 // Log start time
18762 base::TimeTicks start_time = base::TimeTicks::Now();
18763
18764 TestCompletionCallback callback;
18765 auto session = CreateSession(&session_deps_);
18766 auto trans =
18767 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18768 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18769 EXPECT_THAT(callback.GetResult(rv), IsOk());
18770
18771 const HttpResponseInfo* response = trans->GetResponseInfo();
18772 ASSERT_TRUE(response);
18773
18774 EXPECT_TRUE(response->headers);
18775 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18776
18777 std::string response_data;
18778 rv = ReadTransaction(trans.get(), &response_data);
18779 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18780
18781 trans.reset();
18782
18783 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18784
18785 CheckReport(0 /* index */, 200 /* status_code */,
18786 ERR_CONTENT_LENGTH_MISMATCH);
18787 const NetworkErrorLoggingService::RequestDetails& error =
18788 network_error_logging_service()->errors()[0];
18789 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18790}
18791
18792TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18793 CreateReportRestartWithAuth) {
18794 std::string extra_header_string = extra_headers_.ToString();
18795 static const base::TimeDelta kSleepDuration =
18796 base::TimeDelta::FromMilliseconds(10);
18797
18798 MockWrite data_writes1[] = {
18799 MockWrite("GET / HTTP/1.1\r\n"
18800 "Host: www.example.org\r\n"
18801 "Connection: keep-alive\r\n"),
18802 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18803 };
18804
18805 MockRead data_reads1[] = {
18806 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18807 // Give a couple authenticate options (only the middle one is actually
18808 // supported).
18809 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18810 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18811 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18812 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18813 // Large content-length -- won't matter, as connection will be reset.
18814 MockRead("Content-Length: 10000\r\n\r\n"),
18815 MockRead(SYNCHRONOUS, ERR_FAILED),
18816 };
18817
18818 // After calling trans->RestartWithAuth(), this is the request we should
18819 // be issuing -- the final header line contains the credentials.
18820 MockWrite data_writes2[] = {
18821 MockWrite("GET / HTTP/1.1\r\n"
18822 "Host: www.example.org\r\n"
18823 "Connection: keep-alive\r\n"
18824 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18825 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18826 };
18827
18828 // Lastly, the server responds with the actual content.
18829 MockRead data_reads2[] = {
18830 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18831 MockRead("hello world"),
18832 MockRead(SYNCHRONOUS, OK),
18833 };
18834
18835 StaticSocketDataProvider data1(data_reads1, data_writes1);
18836 StaticSocketDataProvider data2(data_reads2, data_writes2);
18837 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18838 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18839
18840 SSLSocketDataProvider ssl1(ASYNC, OK);
18841 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18842 SSLSocketDataProvider ssl2(ASYNC, OK);
18843 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18844
18845 base::TimeTicks start_time = base::TimeTicks::Now();
18846 base::TimeTicks restart_time;
18847
18848 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18849 auto trans =
18850 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18851
18852 TestCompletionCallback callback1;
18853
18854 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18855 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18856
18857 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18858
18859 TestCompletionCallback callback2;
18860
18861 // Wait 10 ms then restart with auth
18862 FastForwardBy(kSleepDuration);
18863 restart_time = base::TimeTicks::Now();
18864 rv =
18865 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18866 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18867
18868 std::string response_data;
18869 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18870 EXPECT_EQ("hello world", response_data);
18871
18872 trans.reset();
18873
18874 // One 401 report for the auth challenge, then a 200 report for the successful
18875 // retry. Note that we don't report the error draining the body, as the first
18876 // request already generated a report for the auth challenge.
18877 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18878
18879 // Check error report contents
18880 CheckReport(0 /* index */, 401 /* status_code */, OK);
18881 CheckReport(1 /* index */, 200 /* status_code */, OK);
18882
18883 const NetworkErrorLoggingService::RequestDetails& error1 =
18884 network_error_logging_service()->errors()[0];
18885 const NetworkErrorLoggingService::RequestDetails& error2 =
18886 network_error_logging_service()->errors()[1];
18887
18888 // Sanity-check elapsed time values
18889 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18890 // Check that the start time is refreshed when restarting with auth.
18891 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18892}
18893
18894// Same as above, except draining the body before restarting fails
18895// asynchronously.
18896TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18897 CreateReportRestartWithAuthAsync) {
18898 std::string extra_header_string = extra_headers_.ToString();
18899 static const base::TimeDelta kSleepDuration =
18900 base::TimeDelta::FromMilliseconds(10);
18901
18902 MockWrite data_writes1[] = {
18903 MockWrite("GET / HTTP/1.1\r\n"
18904 "Host: www.example.org\r\n"
18905 "Connection: keep-alive\r\n"),
18906 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18907 };
18908
18909 MockRead data_reads1[] = {
18910 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18911 // Give a couple authenticate options (only the middle one is actually
18912 // supported).
18913 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18914 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18915 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18916 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18917 // Large content-length -- won't matter, as connection will be reset.
18918 MockRead("Content-Length: 10000\r\n\r\n"),
18919 MockRead(ASYNC, ERR_FAILED),
18920 };
18921
18922 // After calling trans->RestartWithAuth(), this is the request we should
18923 // be issuing -- the final header line contains the credentials.
18924 MockWrite data_writes2[] = {
18925 MockWrite("GET / HTTP/1.1\r\n"
18926 "Host: www.example.org\r\n"
18927 "Connection: keep-alive\r\n"
18928 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18929 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18930 };
18931
18932 // Lastly, the server responds with the actual content.
18933 MockRead data_reads2[] = {
18934 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18935 MockRead("hello world"),
18936 MockRead(SYNCHRONOUS, OK),
18937 };
18938
18939 StaticSocketDataProvider data1(data_reads1, data_writes1);
18940 StaticSocketDataProvider data2(data_reads2, data_writes2);
18941 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18942 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18943
18944 SSLSocketDataProvider ssl1(ASYNC, OK);
18945 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18946 SSLSocketDataProvider ssl2(ASYNC, OK);
18947 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18948
18949 base::TimeTicks start_time = base::TimeTicks::Now();
18950 base::TimeTicks restart_time;
18951
18952 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18953 auto trans =
18954 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18955
18956 TestCompletionCallback callback1;
18957
18958 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18959 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18960
18961 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18962
18963 TestCompletionCallback callback2;
18964
18965 // Wait 10 ms then restart with auth
18966 FastForwardBy(kSleepDuration);
18967 restart_time = base::TimeTicks::Now();
18968 rv =
18969 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18970 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18971
18972 std::string response_data;
18973 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18974 EXPECT_EQ("hello world", response_data);
18975
18976 trans.reset();
18977
18978 // One 401 report for the auth challenge, then a 200 report for the successful
18979 // retry. Note that we don't report the error draining the body, as the first
18980 // request already generated a report for the auth challenge.
18981 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18982
18983 // Check error report contents
18984 CheckReport(0 /* index */, 401 /* status_code */, OK);
18985 CheckReport(1 /* index */, 200 /* status_code */, OK);
18986
18987 const NetworkErrorLoggingService::RequestDetails& error1 =
18988 network_error_logging_service()->errors()[0];
18989 const NetworkErrorLoggingService::RequestDetails& error2 =
18990 network_error_logging_service()->errors()[1];
18991
18992 // Sanity-check elapsed time values
18993 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18994 // Check that the start time is refreshed when restarting with auth.
18995 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18996}
18997
18998TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18999 CreateReportRetryKeepAliveConnectionReset) {
19000 std::string extra_header_string = extra_headers_.ToString();
19001 MockWrite data_writes1[] = {
19002 MockWrite("GET / HTTP/1.1\r\n"
19003 "Host: www.example.org\r\n"
19004 "Connection: keep-alive\r\n"),
19005 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19006 MockWrite("GET / HTTP/1.1\r\n"
19007 "Host: www.example.org\r\n"
19008 "Connection: keep-alive\r\n"),
19009 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19010 };
19011
19012 MockRead data_reads1[] = {
19013 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19014 MockRead("hello"),
19015 // Connection is reset
19016 MockRead(ASYNC, ERR_CONNECTION_RESET),
19017 };
19018
19019 // Successful retry
19020 MockRead data_reads2[] = {
19021 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19022 MockRead("world"),
19023 MockRead(ASYNC, OK),
19024 };
19025
19026 StaticSocketDataProvider data1(data_reads1, data_writes1);
19027 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
19028 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19029 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19030
19031 SSLSocketDataProvider ssl1(ASYNC, OK);
19032 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
19033 SSLSocketDataProvider ssl2(ASYNC, OK);
19034 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
19035
19036 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19037 auto trans1 =
19038 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19039
19040 TestCompletionCallback callback1;
19041
19042 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
19043 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19044
19045 std::string response_data;
19046 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19047 EXPECT_EQ("hello", response_data);
19048
19049 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19050
19051 auto trans2 =
19052 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19053
19054 TestCompletionCallback callback2;
19055
19056 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
19057 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19058
19059 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19060 EXPECT_EQ("world", response_data);
19061
19062 trans1.reset();
19063 trans2.reset();
19064
19065 // One OK report from first request, then a ERR_CONNECTION_RESET report from
19066 // the second request, then an OK report from the successful retry.
19067 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19068
19069 // Check error report contents
19070 CheckReport(0 /* index */, 200 /* status_code */, OK);
19071 CheckReport(1 /* index */, 0 /* status_code */, ERR_CONNECTION_RESET);
19072 CheckReport(2 /* index */, 200 /* status_code */, OK);
19073}
19074
19075TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19076 CreateReportRetryKeepAlive408) {
19077 std::string extra_header_string = extra_headers_.ToString();
19078 MockWrite data_writes1[] = {
19079 MockWrite("GET / HTTP/1.1\r\n"
19080 "Host: www.example.org\r\n"
19081 "Connection: keep-alive\r\n"),
19082 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19083 MockWrite("GET / HTTP/1.1\r\n"
19084 "Host: www.example.org\r\n"
19085 "Connection: keep-alive\r\n"),
19086 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19087 };
19088
19089 MockRead data_reads1[] = {
19090 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19091 MockRead("hello"),
19092 // 408 Request Timeout
19093 MockRead(SYNCHRONOUS,
19094 "HTTP/1.1 408 Request Timeout\r\n"
19095 "Connection: Keep-Alive\r\n"
19096 "Content-Length: 6\r\n\r\n"
19097 "Pickle"),
19098 };
19099
19100 // Successful retry
19101 MockRead data_reads2[] = {
19102 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19103 MockRead("world"),
19104 MockRead(ASYNC, OK),
19105 };
19106
19107 StaticSocketDataProvider data1(data_reads1, data_writes1);
19108 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
19109 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19110 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19111
19112 SSLSocketDataProvider ssl1(ASYNC, OK);
19113 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
19114 SSLSocketDataProvider ssl2(ASYNC, OK);
19115 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
19116
19117 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19118 auto trans1 =
19119 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19120
19121 TestCompletionCallback callback1;
19122
19123 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
19124 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19125
19126 std::string response_data;
19127 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19128 EXPECT_EQ("hello", response_data);
19129
19130 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19131
19132 auto trans2 =
19133 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19134
19135 TestCompletionCallback callback2;
19136
19137 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
19138 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19139
19140 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19141 EXPECT_EQ("world", response_data);
19142
19143 trans1.reset();
19144 trans2.reset();
19145
19146 // One 200 report from first request, then a 408 report from
19147 // the second request, then a 200 report from the successful retry.
19148 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19149
19150 // Check error report contents
19151 CheckReport(0 /* index */, 200 /* status_code */, OK);
19152 CheckReport(1 /* index */, 408 /* status_code */, OK);
19153 CheckReport(2 /* index */, 200 /* status_code */, OK);
19154}
19155
19156TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19157 CreateReportRetry421WithoutConnectionPooling) {
19158 // Two hosts resolve to the same IP address.
19159 const std::string ip_addr = "1.2.3.4";
19160 IPAddress ip;
19161 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
19162 IPEndPoint peer_addr = IPEndPoint(ip, 443);
19163
19164 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
19165 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
19166 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
19167
19168 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19169
19170 // Two requests on the first connection.
19171 spdy::SpdySerializedFrame req1(
19172 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
19173 spdy_util_.UpdateWithStreamDestruction(1);
19174 spdy::SpdySerializedFrame req2(
19175 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
19176 spdy::SpdySerializedFrame rst(
19177 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
19178 MockWrite writes1[] = {
19179 CreateMockWrite(req1, 0),
19180 CreateMockWrite(req2, 3),
19181 CreateMockWrite(rst, 6),
19182 };
19183
19184 // The first one succeeds, the second gets error 421 Misdirected Request.
19185 spdy::SpdySerializedFrame resp1(
19186 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
19187 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
19188 spdy::SpdyHeaderBlock response_headers;
19189 response_headers[spdy::kHttp2StatusHeader] = "421";
19190 spdy::SpdySerializedFrame resp2(
19191 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
19192 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
19193 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
19194
19195 MockConnect connect1(ASYNC, OK, peer_addr);
19196 SequencedSocketData data1(connect1, reads1, writes1);
19197 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19198
19199 AddSSLSocketData();
19200
19201 // Retry the second request on a second connection.
19202 SpdyTestUtil spdy_util2;
19203 spdy::SpdySerializedFrame req3(
19204 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
19205 MockWrite writes2[] = {
19206 CreateMockWrite(req3, 0),
19207 };
19208
19209 spdy::SpdySerializedFrame resp3(
19210 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
19211 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
19212 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
19213 MockRead(ASYNC, 0, 3)};
19214
19215 MockConnect connect2(ASYNC, OK, peer_addr);
19216 SequencedSocketData data2(connect2, reads2, writes2);
19217 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19218
19219 AddSSLSocketData();
19220
19221 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3319222 int rv = session_deps_.host_resolver->LoadIntoCache(
19223 HostPortPair("mail.example.com", 443), base::nullopt);
19224 EXPECT_THAT(rv, IsOk());
Lily Chenfec60d92019-01-24 01:16:4219225
19226 HttpRequestInfo request1;
19227 request1.method = "GET";
19228 request1.url = GURL("https://www.example.org/");
19229 request1.load_flags = 0;
19230 request1.traffic_annotation =
19231 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19232 auto trans1 =
19233 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19234
Eric Orthf4db66a2019-02-19 21:35:3319235 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219236 rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
19237 EXPECT_THAT(callback.GetResult(rv), IsOk());
19238
19239 const HttpResponseInfo* response = trans1->GetResponseInfo();
19240 ASSERT_TRUE(response);
19241 ASSERT_TRUE(response->headers);
19242 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19243 EXPECT_TRUE(response->was_fetched_via_spdy);
19244 EXPECT_TRUE(response->was_alpn_negotiated);
19245 std::string response_data;
19246 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19247 EXPECT_EQ("hello!", response_data);
19248
19249 trans1.reset();
19250
19251 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19252
19253 HttpRequestInfo request2;
19254 request2.method = "GET";
19255 request2.url = GURL("https://mail.example.org/");
19256 request2.load_flags = 0;
19257 request2.traffic_annotation =
19258 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19259 auto trans2 =
19260 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19261
19262 BoundTestNetLog log;
19263 rv = trans2->Start(&request2, callback.callback(), log.bound());
19264 EXPECT_THAT(callback.GetResult(rv), IsOk());
19265
19266 response = trans2->GetResponseInfo();
19267 ASSERT_TRUE(response);
19268 ASSERT_TRUE(response->headers);
19269 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19270 EXPECT_TRUE(response->was_fetched_via_spdy);
19271 EXPECT_TRUE(response->was_alpn_negotiated);
19272 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19273 EXPECT_EQ("hello!", response_data);
19274
19275 trans2.reset();
19276
19277 // One 200 report from the first request, then a 421 report from the
19278 // second request, then a 200 report from the successful retry.
19279 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19280
19281 // Check error report contents
19282 const NetworkErrorLoggingService::RequestDetails& error1 =
19283 network_error_logging_service()->errors()[0];
19284 EXPECT_EQ(GURL("https://www.example.org/"), error1.uri);
19285 EXPECT_TRUE(error1.referrer.is_empty());
19286 EXPECT_EQ("", error1.user_agent);
19287 EXPECT_EQ(ip, error1.server_ip);
19288 EXPECT_EQ("h2", error1.protocol);
19289 EXPECT_EQ("GET", error1.method);
19290 EXPECT_EQ(200, error1.status_code);
19291 EXPECT_EQ(OK, error1.type);
19292 EXPECT_EQ(0, error1.reporting_upload_depth);
19293
19294 const NetworkErrorLoggingService::RequestDetails& error2 =
19295 network_error_logging_service()->errors()[1];
19296 EXPECT_EQ(GURL("https://mail.example.org/"), error2.uri);
19297 EXPECT_TRUE(error2.referrer.is_empty());
19298 EXPECT_EQ("", error2.user_agent);
19299 EXPECT_EQ(ip, error2.server_ip);
19300 EXPECT_EQ("h2", error2.protocol);
19301 EXPECT_EQ("GET", error2.method);
19302 EXPECT_EQ(421, error2.status_code);
19303 EXPECT_EQ(OK, error2.type);
19304 EXPECT_EQ(0, error2.reporting_upload_depth);
19305
19306 const NetworkErrorLoggingService::RequestDetails& error3 =
19307 network_error_logging_service()->errors()[2];
19308 EXPECT_EQ(GURL("https://mail.example.org/"), error3.uri);
19309 EXPECT_TRUE(error3.referrer.is_empty());
19310 EXPECT_EQ("", error3.user_agent);
19311 EXPECT_EQ(ip, error3.server_ip);
19312 EXPECT_EQ("h2", error3.protocol);
19313 EXPECT_EQ("GET", error3.method);
19314 EXPECT_EQ(200, error3.status_code);
19315 EXPECT_EQ(OK, error3.type);
19316 EXPECT_EQ(0, error3.reporting_upload_depth);
Douglas Creageref5eecdc2018-11-09 20:50:3619317}
19318
Lily Chend3930e72019-03-01 19:31:1119319TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19320 CreateReportCancelAfterStart) {
19321 StaticSocketDataProvider data;
19322 data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
19323 session_deps_.socket_factory->AddSocketDataProvider(&data);
19324
19325 TestCompletionCallback callback;
19326 auto session = CreateSession(&session_deps_);
19327 auto trans =
19328 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19329 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19330 EXPECT_EQ(rv, ERR_IO_PENDING);
19331
19332 // Cancel after start.
19333 trans.reset();
19334
19335 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19336 CheckReport(0 /* index */, 0 /* status_code */, ERR_ABORTED,
19337 IPAddress() /* server_ip */);
19338}
19339
19340TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19341 CreateReportCancelBeforeReadingBody) {
19342 std::string extra_header_string = extra_headers_.ToString();
19343 MockWrite data_writes[] = {
19344 MockWrite("GET / HTTP/1.1\r\n"
19345 "Host: www.example.org\r\n"
19346 "Connection: keep-alive\r\n"),
19347 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19348 };
19349 MockRead data_reads[] = {
19350 MockRead("HTTP/1.0 200 OK\r\n"),
19351 MockRead("Content-Length: 100\r\n\r\n"), // Body is never read.
19352 };
19353
19354 StaticSocketDataProvider data(data_reads, data_writes);
19355 session_deps_.socket_factory->AddSocketDataProvider(&data);
19356
19357 SSLSocketDataProvider ssl(ASYNC, OK);
19358 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19359
19360 TestCompletionCallback callback;
19361 auto session = CreateSession(&session_deps_);
19362 auto trans =
19363 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19364 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19365 EXPECT_THAT(callback.GetResult(rv), IsOk());
19366
19367 const HttpResponseInfo* response = trans->GetResponseInfo();
19368 ASSERT_TRUE(response);
19369
19370 EXPECT_TRUE(response->headers);
19371 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
19372
19373 // Cancel before reading the body.
19374 trans.reset();
19375
19376 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19377 CheckReport(0 /* index */, 200 /* status_code */, ERR_ABORTED);
19378}
19379
Lily Chen00196ab62018-12-04 19:52:2919380TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) {
19381 base::HistogramTester histograms;
19382 RequestPolicy();
19383 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19384 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19385
19386 // Make HTTP request
19387 std::string extra_header_string = extra_headers_.ToString();
19388 MockRead data_reads[] = {
19389 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
19390 MockRead("hello world"),
19391 MockRead(SYNCHRONOUS, OK),
19392 };
19393 MockWrite data_writes[] = {
19394 MockWrite("GET / HTTP/1.1\r\n"
19395 "Host: www.example.org\r\n"
19396 "Connection: keep-alive\r\n"),
19397 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19398 };
19399
Lily Chend3930e72019-03-01 19:31:1119400 StaticSocketDataProvider data(data_reads, data_writes);
19401 session_deps_.socket_factory->AddSocketDataProvider(&data);
Lily Chen00196ab62018-12-04 19:52:2919402
Lily Chenfec60d92019-01-24 01:16:4219403 // Insecure url
19404 url_ = "http://www.example.org/";
19405 request_.url = GURL(url_);
19406
Lily Chen00196ab62018-12-04 19:52:2919407 TestCompletionCallback callback;
19408 auto session = CreateSession(&session_deps_);
Lily Chenfec60d92019-01-24 01:16:4219409 auto trans =
19410 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19411 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19412 EXPECT_THAT(callback.GetResult(rv), IsOk());
19413
19414 std::string response_data;
19415 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19416 EXPECT_EQ("hello world", response_data);
Lily Chen00196ab62018-12-04 19:52:2919417
19418 // Insecure request does not generate a report
19419 histograms.ExpectBucketCount(
19420 NetworkErrorLoggingService::kRequestOutcomeHistogram,
Tsuyoshi Horo0b042232019-03-06 01:11:0519421 NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1);
Lily Chen00196ab62018-12-04 19:52:2919422
19423 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19424}
19425
19426TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19427 DontCreateReportHttpError) {
19428 base::HistogramTester histograms;
19429 RequestPolicy();
19430 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19431 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19432
19433 // Make HTTP request that fails
19434 MockRead data_reads[] = {
19435 MockRead("hello world"),
19436 MockRead(SYNCHRONOUS, OK),
19437 };
19438
19439 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
19440 session_deps_.socket_factory->AddSocketDataProvider(&data);
19441
Lily Chenfec60d92019-01-24 01:16:4219442 url_ = "http://www.originwithoutpolicy.com:2000/";
19443 request_.url = GURL(url_);
19444
Lily Chen00196ab62018-12-04 19:52:2919445 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19446
Lily Chen00196ab62018-12-04 19:52:2919447 auto trans =
19448 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Lily Chen00196ab62018-12-04 19:52:2919449 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219450 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
Lily Chen00196ab62018-12-04 19:52:2919451 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
19452
19453 // Insecure request does not generate a report, regardless of existence of a
19454 // policy for the origin.
19455 histograms.ExpectBucketCount(
19456 NetworkErrorLoggingService::kRequestOutcomeHistogram,
Tsuyoshi Horo0b042232019-03-06 01:11:0519457 NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1);
Lily Chen00196ab62018-12-04 19:52:2919458
19459 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19460}
19461
Lily Chen90ae93cc2019-02-14 01:15:3919462// Don't report on proxy auth challenges, don't report if connecting through a
19463// proxy.
19464TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportProxy) {
19465 HttpRequestInfo request;
19466 request.method = "GET";
19467 request.url = GURL("https://www.example.org/");
19468 request.traffic_annotation =
19469 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19470
19471 // Configure against proxy server "myproxy:70".
19472 session_deps_.proxy_resolution_service =
19473 ProxyResolutionService::CreateFixedFromPacResult(
19474 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
19475 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19476
19477 // Since we have proxy, should try to establish tunnel.
19478 MockWrite data_writes1[] = {
19479 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19480 "Host: www.example.org:443\r\n"
19481 "Proxy-Connection: keep-alive\r\n\r\n"),
19482 };
19483
19484 // The proxy responds to the connect with a 407, using a non-persistent
19485 // connection.
19486 MockRead data_reads1[] = {
19487 // No credentials.
19488 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
19489 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19490 MockRead("Proxy-Connection: close\r\n\r\n"),
19491 };
19492
19493 MockWrite data_writes2[] = {
19494 // After calling trans->RestartWithAuth(), this is the request we should
19495 // be issuing -- the final header line contains the credentials.
19496 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19497 "Host: www.example.org:443\r\n"
19498 "Proxy-Connection: keep-alive\r\n"
19499 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19500
19501 MockWrite("GET / HTTP/1.1\r\n"
19502 "Host: www.example.org\r\n"
19503 "Connection: keep-alive\r\n\r\n"),
19504 };
19505
19506 MockRead data_reads2[] = {
19507 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
19508
19509 MockRead("HTTP/1.1 200 OK\r\n"),
19510 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19511 MockRead("Content-Length: 5\r\n\r\n"),
19512 MockRead(SYNCHRONOUS, "hello"),
19513 };
19514
19515 StaticSocketDataProvider data1(data_reads1, data_writes1);
19516 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19517 StaticSocketDataProvider data2(data_reads2, data_writes2);
19518 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19519 SSLSocketDataProvider ssl(ASYNC, OK);
19520 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19521
19522 TestCompletionCallback callback1;
19523
19524 auto trans =
19525 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19526
19527 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
19528 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19529
19530 const HttpResponseInfo* response = trans->GetResponseInfo();
19531 EXPECT_EQ(407, response->headers->response_code());
19532
19533 std::string response_data;
19534 rv = ReadTransaction(trans.get(), &response_data);
19535 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
19536
19537 // No NEL report is generated for the 407.
19538 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19539
19540 TestCompletionCallback callback2;
19541
19542 rv =
19543 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
19544 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19545
19546 response = trans->GetResponseInfo();
19547 EXPECT_EQ(200, response->headers->response_code());
19548
19549 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19550 EXPECT_EQ("hello", response_data);
19551
19552 trans.reset();
19553
19554 // No NEL report is generated because we are behind a proxy.
19555 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19556}
19557
Douglas Creageref5eecdc2018-11-09 20:50:3619558TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19559 ReportContainsUploadDepth) {
19560 reporting_upload_depth_ = 7;
Lily Chenfec60d92019-01-24 01:16:4219561 request_.reporting_upload_depth = reporting_upload_depth_;
Douglas Creageref5eecdc2018-11-09 20:50:3619562 RequestPolicy();
19563 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219564 const NetworkErrorLoggingService::RequestDetails& error =
19565 network_error_logging_service()->errors()[0];
Douglas Creageref5eecdc2018-11-09 20:50:3619566 EXPECT_EQ(7, error.reporting_upload_depth);
19567}
19568
Lily Chenfec60d92019-01-24 01:16:4219569TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportElapsedTime) {
19570 std::string extra_header_string = extra_headers_.ToString();
19571 static const base::TimeDelta kSleepDuration =
19572 base::TimeDelta::FromMilliseconds(10);
19573
19574 std::vector<MockWrite> data_writes = {
19575 MockWrite(ASYNC, 0,
19576 "GET / HTTP/1.1\r\n"
19577 "Host: www.example.org\r\n"
19578 "Connection: keep-alive\r\n"),
19579 MockWrite(ASYNC, 1, extra_header_string.data()),
19580 };
19581
19582 std::vector<MockRead> data_reads = {
19583 // Write one byte of the status line, followed by a pause.
19584 MockRead(ASYNC, 2, "H"),
19585 MockRead(ASYNC, ERR_IO_PENDING, 3),
19586 MockRead(ASYNC, 4, "TTP/1.1 200 OK\r\n\r\n"),
19587 MockRead(ASYNC, 5, "hello world"),
19588 MockRead(SYNCHRONOUS, OK, 6),
19589 };
19590
19591 SequencedSocketData data(data_reads, data_writes);
19592 session_deps_.socket_factory->AddSocketDataProvider(&data);
19593
19594 SSLSocketDataProvider ssl(ASYNC, OK);
19595 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19596
19597 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19598
19599 auto trans =
19600 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19601
19602 TestCompletionCallback callback;
19603
19604 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19606
19607 data.RunUntilPaused();
19608 ASSERT_TRUE(data.IsPaused());
19609 FastForwardBy(kSleepDuration);
19610 data.Resume();
19611
19612 EXPECT_THAT(callback.GetResult(rv), IsOk());
19613
19614 std::string response_data;
19615 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19616 EXPECT_EQ("hello world", response_data);
19617
19618 trans.reset();
19619
Douglas Creageref5eecdc2018-11-09 20:50:3619620 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219621
19622 CheckReport(0 /* index */, 200 /* status_code */, OK);
19623
19624 const NetworkErrorLoggingService::RequestDetails& error =
19625 network_error_logging_service()->errors()[0];
19626
19627 // Sanity-check elapsed time in error report
19628 EXPECT_EQ(kSleepDuration, error.elapsed_time);
Douglas Creageref5eecdc2018-11-09 20:50:3619629}
Lily Chenfec60d92019-01-24 01:16:4219630
Douglas Creager3cb042052018-11-06 23:08:5219631#endif // BUILDFLAG(ENABLE_REPORTING)
19632
[email protected]89ceba9a2009-03-21 03:46:0619633} // namespace net