blob: c8545832c62a5e8c03566801b5b471dc39d506a2 [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,
Matt Menkebf3c767d2019-04-15 23:28:24696 int64_t generation) override {}
dmichaeld6e570d2014-12-18 22:30:57697 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.
Emily Starkf2c9bbd2019-04-09 17:08:58719bool CheckBasicServerAuth(
720 const base::Optional<AuthChallengeInfo>& auth_challenge) {
[email protected]79cb5c12011-09-12 13:12:04721 if (!auth_challenge)
722 return false;
723 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43724 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04725 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19726 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04727 return true;
728}
729
Emily Starkf2c9bbd2019-04-09 17:08:58730bool CheckBasicProxyAuth(
731 const base::Optional<AuthChallengeInfo>& auth_challenge) {
[email protected]79cb5c12011-09-12 13:12:04732 if (!auth_challenge)
733 return false;
734 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43735 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
736 EXPECT_EQ("MyRealm1", auth_challenge->realm);
737 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
738 return true;
739}
740
Emily Starkf2c9bbd2019-04-09 17:08:58741bool CheckBasicSecureProxyAuth(
742 const base::Optional<AuthChallengeInfo>& auth_challenge) {
asanka098c0092016-06-16 20:18:43743 if (!auth_challenge)
744 return false;
745 EXPECT_TRUE(auth_challenge->is_proxy);
746 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04747 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19748 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04749 return true;
750}
751
Emily Starkf2c9bbd2019-04-09 17:08:58752bool CheckDigestServerAuth(
753 const base::Optional<AuthChallengeInfo>& auth_challenge) {
[email protected]79cb5c12011-09-12 13:12:04754 if (!auth_challenge)
755 return false;
756 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43757 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04758 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19759 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04760 return true;
761}
762
thakis84dff942015-07-28 20:47:38763#if defined(NTLM_PORTABLE)
Emily Starkf2c9bbd2019-04-09 17:08:58764bool CheckNTLMServerAuth(
765 const base::Optional<AuthChallengeInfo>& auth_challenge) {
[email protected]79cb5c12011-09-12 13:12:04766 if (!auth_challenge)
767 return false;
768 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55769 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04770 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19771 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04772 return true;
773}
David Benjamin5cb91132018-04-06 05:54:49774
Emily Starkf2c9bbd2019-04-09 17:08:58775bool CheckNTLMProxyAuth(
776 const base::Optional<AuthChallengeInfo>& auth_challenge) {
David Benjamin5cb91132018-04-06 05:54:49777 if (!auth_challenge)
778 return false;
779 EXPECT_TRUE(auth_challenge->is_proxy);
780 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
781 EXPECT_EQ(std::string(), auth_challenge->realm);
782 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
783 return true;
784}
thakis84dff942015-07-28 20:47:38785#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04786
[email protected]448d4ca52012-03-04 04:12:23787} // namespace
788
bncd16676a2016-07-20 16:23:01789TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09790 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16791 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27792}
793
bncd16676a2016-07-20 16:23:01794TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27795 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35796 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
797 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06798 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27799 };
Ryan Sleevib8d7ea02018-05-07 20:01:01800 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01801 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27802 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
803 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01804 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22805 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47806 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59807
808 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27809}
810
811// Response with no status line.
bncd16676a2016-07-20 16:23:01812TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27813 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35814 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06815 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27816 };
Ryan Sleevib8d7ea02018-05-07 20:01:01817 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41818 EXPECT_THAT(out.rv, IsOk());
819 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
820 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01821 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41822 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27823}
824
mmenkea7da6da2016-09-01 21:56:52825// Response with no status line, and a weird port. Should fail by default.
826TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
827 MockRead data_reads[] = {
828 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
829 };
830
Ryan Sleevib8d7ea02018-05-07 20:01:01831 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52832 session_deps_.socket_factory->AddSocketDataProvider(&data);
833
834 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
835
krasinc06a72a2016-12-21 03:42:46836 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58837 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19838 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52839
mmenkea7da6da2016-09-01 21:56:52840 request.method = "GET";
841 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10842 request.traffic_annotation =
843 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
844
mmenkea7da6da2016-09-01 21:56:52845 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20846 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52847 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
848}
849
Shivani Sharmafdcaefd2017-11-02 00:12:26850// Tests that request info can be destroyed after the headers phase is complete.
851TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
852 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
853 auto trans =
854 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
855
856 MockRead data_reads[] = {
857 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
858 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
859 };
Ryan Sleevib8d7ea02018-05-07 20:01:01860 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Shivani Sharmafdcaefd2017-11-02 00:12:26861 session_deps_.socket_factory->AddSocketDataProvider(&data);
862
863 TestCompletionCallback callback;
864
865 {
866 auto request = std::make_unique<HttpRequestInfo>();
867 request->method = "GET";
868 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10869 request->traffic_annotation =
870 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26871
872 int rv =
873 trans->Start(request.get(), callback.callback(), NetLogWithSource());
874
875 EXPECT_THAT(callback.GetResult(rv), IsOk());
876 } // Let request info be destroyed.
877
878 trans.reset();
879}
880
mmenkea7da6da2016-09-01 21:56:52881// Response with no status line, and a weird port. Option to allow weird ports
882// enabled.
883TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
884 MockRead data_reads[] = {
885 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
886 };
887
Ryan Sleevib8d7ea02018-05-07 20:01:01888 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52889 session_deps_.socket_factory->AddSocketDataProvider(&data);
890 session_deps_.http_09_on_non_default_ports_enabled = true;
891 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
892
krasinc06a72a2016-12-21 03:42:46893 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58894 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19895 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52896
mmenkea7da6da2016-09-01 21:56:52897 request.method = "GET";
898 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10899 request.traffic_annotation =
900 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
901
mmenkea7da6da2016-09-01 21:56:52902 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20903 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52904 EXPECT_THAT(callback.GetResult(rv), IsOk());
905
906 const HttpResponseInfo* info = trans->GetResponseInfo();
907 ASSERT_TRUE(info->headers);
908 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
909
910 // Don't bother to read the body - that's verified elsewhere, important thing
911 // is that the option to allow HTTP/0.9 on non-default ports is respected.
912}
913
[email protected]231d5a32008-09-13 00:45:27914// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01915TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27916 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35917 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06918 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27919 };
Ryan Sleevib8d7ea02018-05-07 20:01:01920 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01921 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27922 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
923 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01924 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22925 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27926}
927
928// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01929TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27930 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35931 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06932 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27933 };
Ryan Sleevib8d7ea02018-05-07 20:01:01934 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01935 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27936 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
937 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01938 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22939 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27940}
941
942// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01943TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27944 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35945 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06946 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27947 };
Ryan Sleevib8d7ea02018-05-07 20:01:01948 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41949 EXPECT_THAT(out.rv, IsOk());
950 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
951 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01952 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41953 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27954}
955
956// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01957TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27958 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35959 MockRead("\n"),
960 MockRead("\n"),
961 MockRead("Q"),
962 MockRead("J"),
963 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06964 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27965 };
Ryan Sleevib8d7ea02018-05-07 20:01:01966 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01967 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27968 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
969 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01970 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22971 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27972}
973
974// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01975TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27976 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35977 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06978 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27979 };
Ryan Sleevib8d7ea02018-05-07 20:01:01980 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41981 EXPECT_THAT(out.rv, IsOk());
982 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
983 EXPECT_EQ("HTT", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01984 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41985 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52986}
987
[email protected]f9d44aa2008-09-23 23:57:17988// Simulate a 204 response, lacking a Content-Length header, sent over a
989// persistent connection. The response should still terminate since a 204
990// cannot have a response body.
bncd16676a2016-07-20 16:23:01991TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19992 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17993 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35994 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19995 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06996 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17997 };
Ryan Sleevib8d7ea02018-05-07 20:01:01998 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01999 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:171000 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1001 EXPECT_EQ("", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011002 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221003 int64_t response_size = reads_size - strlen(junk);
1004 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171005}
1006
[email protected]0877e3d2009-10-17 22:29:571007// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011008TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191009 std::string final_chunk = "0\r\n\r\n";
1010 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1011 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571012 MockRead data_reads[] = {
1013 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1014 MockRead("5\r\nHello\r\n"),
1015 MockRead("1\r\n"),
1016 MockRead(" \r\n"),
1017 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191018 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061019 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571020 };
Ryan Sleevib8d7ea02018-05-07 20:01:011021 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011022 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571023 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1024 EXPECT_EQ("Hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011025 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221026 int64_t response_size = reads_size - extra_data.size();
1027 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571028}
1029
[email protected]9fe44f52010-09-23 18:36:001030// Next tests deal with http://crbug.com/56344.
1031
bncd16676a2016-07-20 16:23:011032TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001033 MultipleContentLengthHeadersNoTransferEncoding) {
1034 MockRead data_reads[] = {
1035 MockRead("HTTP/1.1 200 OK\r\n"),
1036 MockRead("Content-Length: 10\r\n"),
1037 MockRead("Content-Length: 5\r\n\r\n"),
1038 };
Ryan Sleevib8d7ea02018-05-07 20:01:011039 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011040 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001041}
1042
bncd16676a2016-07-20 16:23:011043TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041044 DuplicateContentLengthHeadersNoTransferEncoding) {
1045 MockRead data_reads[] = {
1046 MockRead("HTTP/1.1 200 OK\r\n"),
1047 MockRead("Content-Length: 5\r\n"),
1048 MockRead("Content-Length: 5\r\n\r\n"),
1049 MockRead("Hello"),
1050 };
Ryan Sleevib8d7ea02018-05-07 20:01:011051 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011052 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041053 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1054 EXPECT_EQ("Hello", out.response_data);
1055}
1056
bncd16676a2016-07-20 16:23:011057TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041058 ComplexContentLengthHeadersNoTransferEncoding) {
1059 // More than 2 dupes.
1060 {
1061 MockRead data_reads[] = {
1062 MockRead("HTTP/1.1 200 OK\r\n"),
1063 MockRead("Content-Length: 5\r\n"),
1064 MockRead("Content-Length: 5\r\n"),
1065 MockRead("Content-Length: 5\r\n\r\n"),
1066 MockRead("Hello"),
1067 };
Ryan Sleevib8d7ea02018-05-07 20:01:011068 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011069 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041070 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1071 EXPECT_EQ("Hello", out.response_data);
1072 }
1073 // HTTP/1.0
1074 {
1075 MockRead data_reads[] = {
1076 MockRead("HTTP/1.0 200 OK\r\n"),
1077 MockRead("Content-Length: 5\r\n"),
1078 MockRead("Content-Length: 5\r\n"),
1079 MockRead("Content-Length: 5\r\n\r\n"),
1080 MockRead("Hello"),
1081 };
Ryan Sleevib8d7ea02018-05-07 20:01:011082 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011083 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041084 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1085 EXPECT_EQ("Hello", out.response_data);
1086 }
1087 // 2 dupes and one mismatched.
1088 {
1089 MockRead data_reads[] = {
1090 MockRead("HTTP/1.1 200 OK\r\n"),
1091 MockRead("Content-Length: 10\r\n"),
1092 MockRead("Content-Length: 10\r\n"),
1093 MockRead("Content-Length: 5\r\n\r\n"),
1094 };
Ryan Sleevib8d7ea02018-05-07 20:01:011095 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011096 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041097 }
1098}
1099
bncd16676a2016-07-20 16:23:011100TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001101 MultipleContentLengthHeadersTransferEncoding) {
1102 MockRead data_reads[] = {
1103 MockRead("HTTP/1.1 200 OK\r\n"),
1104 MockRead("Content-Length: 666\r\n"),
1105 MockRead("Content-Length: 1337\r\n"),
1106 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1107 MockRead("5\r\nHello\r\n"),
1108 MockRead("1\r\n"),
1109 MockRead(" \r\n"),
1110 MockRead("5\r\nworld\r\n"),
1111 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061112 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001113 };
Ryan Sleevib8d7ea02018-05-07 20:01:011114 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011115 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001116 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1117 EXPECT_EQ("Hello world", out.response_data);
1118}
1119
[email protected]1628fe92011-10-04 23:04:551120// Next tests deal with http://crbug.com/98895.
1121
1122// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011123TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551124 MockRead data_reads[] = {
1125 MockRead("HTTP/1.1 200 OK\r\n"),
1126 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1127 MockRead("Content-Length: 5\r\n\r\n"),
1128 MockRead("Hello"),
1129 };
Ryan Sleevib8d7ea02018-05-07 20:01:011130 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011131 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551132 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1133 EXPECT_EQ("Hello", out.response_data);
1134}
1135
[email protected]54a9c6e52012-03-21 20:10:591136// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011137TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551138 MockRead data_reads[] = {
1139 MockRead("HTTP/1.1 200 OK\r\n"),
1140 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1141 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1142 MockRead("Content-Length: 5\r\n\r\n"),
1143 MockRead("Hello"),
1144 };
Ryan Sleevib8d7ea02018-05-07 20:01:011145 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011146 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591147 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1148 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551149}
1150
1151// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011152TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551153 MockRead data_reads[] = {
1154 MockRead("HTTP/1.1 200 OK\r\n"),
1155 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1156 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1157 MockRead("Content-Length: 5\r\n\r\n"),
1158 MockRead("Hello"),
1159 };
Ryan Sleevib8d7ea02018-05-07 20:01:011160 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011161 EXPECT_THAT(out.rv,
1162 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551163}
1164
[email protected]54a9c6e52012-03-21 20:10:591165// Checks that two identical Location headers result in no error.
1166// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011167TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551168 MockRead data_reads[] = {
1169 MockRead("HTTP/1.1 302 Redirect\r\n"),
1170 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591171 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551172 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061173 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551174 };
1175
1176 HttpRequestInfo request;
1177 request.method = "GET";
1178 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101179 request.traffic_annotation =
1180 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551181
danakj1fd259a02016-04-16 03:17:091182 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161183 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551184
Ryan Sleevib8d7ea02018-05-07 20:01:011185 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071186 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551187
[email protected]49639fa2011-12-20 23:22:411188 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551189
tfarina42834112016-09-22 13:38:201190 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011191 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551192
robpercival214763f2016-07-01 23:27:011193 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551194
bnc691fda62016-08-12 00:43:161195 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521196 ASSERT_TRUE(response);
1197 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551198 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1199 std::string url;
1200 EXPECT_TRUE(response->headers->IsRedirect(&url));
1201 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471202 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551203}
1204
[email protected]1628fe92011-10-04 23:04:551205// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011206TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551207 MockRead data_reads[] = {
1208 MockRead("HTTP/1.1 302 Redirect\r\n"),
1209 MockRead("Location: http://good.com/\r\n"),
1210 MockRead("Location: http://evil.com/\r\n"),
1211 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061212 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551213 };
Ryan Sleevib8d7ea02018-05-07 20:01:011214 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011215 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551216}
1217
[email protected]ef0faf2e72009-03-05 23:27:231218// Do a request using the HEAD method. Verify that we don't try to read the
1219// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011220TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421221 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231222 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231223 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101224 request.traffic_annotation =
1225 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231226
danakj1fd259a02016-04-16 03:17:091227 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161228 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091229 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161230 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091231 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1232 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271233
[email protected]ef0faf2e72009-03-05 23:27:231234 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131235 MockWrite("HEAD / HTTP/1.1\r\n"
1236 "Host: www.example.org\r\n"
1237 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231238 };
1239 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231240 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1241 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231242
mmenked39192ee2015-12-09 00:57:231243 // No response body because the test stops reading here.
1244 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231245 };
1246
Ryan Sleevib8d7ea02018-05-07 20:01:011247 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:071248 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231249
[email protected]49639fa2011-12-20 23:22:411250 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231251
tfarina42834112016-09-22 13:38:201252 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011253 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231254
1255 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011256 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231257
bnc691fda62016-08-12 00:43:161258 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521259 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231260
1261 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521262 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231263 EXPECT_EQ(1234, response->headers->GetContentLength());
1264 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471265 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091266 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1267 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231268
1269 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101270 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231271 bool has_server_header = response->headers->EnumerateHeader(
1272 &iter, "Server", &server_header);
1273 EXPECT_TRUE(has_server_header);
1274 EXPECT_EQ("Blah", server_header);
1275
1276 // Reading should give EOF right away, since there is no message body
1277 // (despite non-zero content-length).
1278 std::string response_data;
bnc691fda62016-08-12 00:43:161279 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011280 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231281 EXPECT_EQ("", response_data);
1282}
1283
bncd16676a2016-07-20 16:23:011284TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091285 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521286
1287 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351288 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1289 MockRead("hello"),
1290 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1291 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061292 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521293 };
Ryan Sleevib8d7ea02018-05-07 20:01:011294 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071295 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521296
[email protected]0b0bf032010-09-21 18:08:501297 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521298 "hello", "world"
1299 };
1300
1301 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421302 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521303 request.method = "GET";
bncce36dca22015-04-21 22:11:231304 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101305 request.traffic_annotation =
1306 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521307
bnc691fda62016-08-12 00:43:161308 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271309
[email protected]49639fa2011-12-20 23:22:411310 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521311
tfarina42834112016-09-22 13:38:201312 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011313 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521314
1315 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011316 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521317
bnc691fda62016-08-12 00:43:161318 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521319 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521320
wezca1070932016-05-26 20:30:521321 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251322 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471323 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521324
1325 std::string response_data;
bnc691fda62016-08-12 00:43:161326 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011327 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251328 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521329 }
1330}
1331
bncd16676a2016-07-20 16:23:011332TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091333 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221334 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191335 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221336 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271337
[email protected]1c773ea12009-04-28 19:58:421338 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521339 request.method = "POST";
1340 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271341 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:101342 request.traffic_annotation =
1343 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521344
shivanishab9a143952016-09-19 17:23:411345 // Check the upload progress returned before initialization is correct.
1346 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1347 EXPECT_EQ(0u, progress.size());
1348 EXPECT_EQ(0u, progress.position());
1349
danakj1fd259a02016-04-16 03:17:091350 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161351 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271352
initial.commit586acc5fe2008-07-26 22:42:521353 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351354 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1355 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1356 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061357 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521358 };
Ryan Sleevib8d7ea02018-05-07 20:01:011359 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071360 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521361
[email protected]49639fa2011-12-20 23:22:411362 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521363
tfarina42834112016-09-22 13:38:201364 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011365 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521366
1367 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011368 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521369
bnc691fda62016-08-12 00:43:161370 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521371 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521372
wezca1070932016-05-26 20:30:521373 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251374 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521375
1376 std::string response_data;
bnc691fda62016-08-12 00:43:161377 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011378 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251379 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521380}
1381
[email protected]3a2d3662009-03-27 03:49:141382// This test is almost the same as Ignores100 above, but the response contains
1383// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571384// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011385TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421386 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141387 request.method = "GET";
1388 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101389 request.traffic_annotation =
1390 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141391
danakj1fd259a02016-04-16 03:17:091392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161393 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271394
[email protected]3a2d3662009-03-27 03:49:141395 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571396 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1397 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141398 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061399 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141400 };
Ryan Sleevib8d7ea02018-05-07 20:01:011401 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071402 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141403
[email protected]49639fa2011-12-20 23:22:411404 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141405
tfarina42834112016-09-22 13:38:201406 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011407 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141408
1409 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011410 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141411
bnc691fda62016-08-12 00:43:161412 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521413 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141414
wezca1070932016-05-26 20:30:521415 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141416 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1417
1418 std::string response_data;
bnc691fda62016-08-12 00:43:161419 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011420 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141421 EXPECT_EQ("hello world", response_data);
1422}
1423
Andrew Comminos517a92c2019-01-14 17:49:561424TEST_F(HttpNetworkTransactionTest, LoadTimingMeasuresTimeToFirstByteForHttp) {
1425 static const base::TimeDelta kDelayAfterFirstByte =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381426 base::TimeDelta::FromMilliseconds(10);
1427
1428 HttpRequestInfo request;
1429 request.method = "GET";
1430 request.url = GURL("http://www.foo.com/");
1431 request.traffic_annotation =
1432 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1433
1434 std::vector<MockWrite> data_writes = {
1435 MockWrite(ASYNC, 0,
1436 "GET / HTTP/1.1\r\n"
1437 "Host: www.foo.com\r\n"
1438 "Connection: keep-alive\r\n\r\n"),
1439 };
1440
1441 std::vector<MockRead> data_reads = {
1442 // Write one byte of the status line, followed by a pause.
1443 MockRead(ASYNC, 1, "H"),
1444 MockRead(ASYNC, ERR_IO_PENDING, 2),
1445 MockRead(ASYNC, 3, "TTP/1.1 200 OK\r\n\r\n"),
1446 MockRead(ASYNC, 4, "hello world"),
1447 MockRead(SYNCHRONOUS, OK, 5),
1448 };
1449
1450 SequencedSocketData data(data_reads, data_writes);
1451 session_deps_.socket_factory->AddSocketDataProvider(&data);
1452
1453 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1454
1455 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1456
1457 TestCompletionCallback callback;
1458
1459 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1460 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1461
1462 data.RunUntilPaused();
1463 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561464 FastForwardBy(kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381465 data.Resume();
1466
1467 rv = callback.WaitForResult();
1468 EXPECT_THAT(rv, IsOk());
1469
1470 const HttpResponseInfo* response = trans.GetResponseInfo();
1471 ASSERT_TRUE(response);
1472
1473 EXPECT_TRUE(response->headers);
1474 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1475
1476 LoadTimingInfo load_timing_info;
1477 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1478 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1479 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561480 // Ensure we didn't include the delay in the TTFB time.
1481 EXPECT_EQ(load_timing_info.receive_headers_start,
1482 load_timing_info.connect_timing.connect_end);
1483 // Ensure that the mock clock advanced at all.
1484 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1485 kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381486
1487 std::string response_data;
1488 rv = ReadTransaction(&trans, &response_data);
1489 EXPECT_THAT(rv, IsOk());
1490 EXPECT_EQ("hello world", response_data);
1491}
1492
1493// Tests that the time-to-first-byte reported in a transaction's load timing
1494// info uses the first response, even if 1XX/informational.
1495void HttpNetworkTransactionTest::Check100ResponseTiming(bool use_spdy) {
Andrew Comminos517a92c2019-01-14 17:49:561496 static const base::TimeDelta kDelayAfter100Response =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381497 base::TimeDelta::FromMilliseconds(10);
1498
1499 HttpRequestInfo request;
1500 request.method = "GET";
1501 request.url = GURL("https://www.foo.com/");
1502 request.traffic_annotation =
1503 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1504
1505 SSLSocketDataProvider ssl(ASYNC, OK);
1506 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1507
1508 std::vector<MockWrite> data_writes;
1509 std::vector<MockRead> data_reads;
1510
1511 spdy::SpdySerializedFrame spdy_req(
1512 spdy_util_.ConstructSpdyGet(request.url.spec().c_str(), 1, LOWEST));
1513
1514 spdy::SpdyHeaderBlock spdy_resp1_headers;
1515 spdy_resp1_headers[spdy::kHttp2StatusHeader] = "100";
1516 spdy::SpdySerializedFrame spdy_resp1(
1517 spdy_util_.ConstructSpdyReply(1, spdy_resp1_headers.Clone()));
1518 spdy::SpdySerializedFrame spdy_resp2(
1519 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1520 spdy::SpdySerializedFrame spdy_data(
1521 spdy_util_.ConstructSpdyDataFrame(1, "hello world", true));
1522
1523 if (use_spdy) {
1524 ssl.next_proto = kProtoHTTP2;
1525
1526 data_writes = {CreateMockWrite(spdy_req, 0)};
1527
1528 data_reads = {
1529 CreateMockRead(spdy_resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
1530 CreateMockRead(spdy_resp2, 3), CreateMockRead(spdy_data, 4),
1531 MockRead(SYNCHRONOUS, OK, 5),
1532 };
1533 } else {
1534 data_writes = {
1535 MockWrite(ASYNC, 0,
1536 "GET / HTTP/1.1\r\n"
1537 "Host: www.foo.com\r\n"
1538 "Connection: keep-alive\r\n\r\n"),
1539 };
1540
1541 data_reads = {
1542 MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
1543 MockRead(ASYNC, ERR_IO_PENDING, 2),
1544
1545 MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1546 MockRead(ASYNC, 4, "hello world"),
1547 MockRead(SYNCHRONOUS, OK, 5),
1548 };
1549 }
1550
1551 SequencedSocketData data(data_reads, data_writes);
1552 session_deps_.socket_factory->AddSocketDataProvider(&data);
1553
1554 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1555
1556 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1557
1558 TestCompletionCallback callback;
1559
1560 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1561 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1562
1563 data.RunUntilPaused();
1564 // We should now have parsed the 100 response and hit ERR_IO_PENDING. Insert
1565 // the delay before parsing the 200 response.
1566 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561567 FastForwardBy(kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381568 data.Resume();
1569
1570 rv = callback.WaitForResult();
1571 EXPECT_THAT(rv, IsOk());
1572
1573 const HttpResponseInfo* response = trans.GetResponseInfo();
1574 ASSERT_TRUE(response);
1575
1576 LoadTimingInfo load_timing_info;
1577 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1578 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1579 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561580 // Ensure we didn't include the delay in the TTFB time.
1581 EXPECT_EQ(load_timing_info.receive_headers_start,
1582 load_timing_info.connect_timing.connect_end);
1583 // Ensure that the mock clock advanced at all.
1584 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1585 kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381586
1587 std::string response_data;
1588 rv = ReadTransaction(&trans, &response_data);
1589 EXPECT_THAT(rv, IsOk());
1590 EXPECT_EQ("hello world", response_data);
1591}
1592
Andrew Comminos517a92c2019-01-14 17:49:561593TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForHttp) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381594 Check100ResponseTiming(false /* use_spdy */);
1595}
1596
Andrew Comminos517a92c2019-01-14 17:49:561597TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForSpdy) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381598 Check100ResponseTiming(true /* use_spdy */);
1599}
1600
bncd16676a2016-07-20 16:23:011601TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081602 HttpRequestInfo request;
1603 request.method = "POST";
1604 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101605 request.traffic_annotation =
1606 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081607
danakj1fd259a02016-04-16 03:17:091608 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161609 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081610
1611 MockRead data_reads[] = {
1612 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1613 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381614 };
Ryan Sleevib8d7ea02018-05-07 20:01:011615 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
zmo9528c9f42015-08-04 22:12:081616 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381617
zmo9528c9f42015-08-04 22:12:081618 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381619
tfarina42834112016-09-22 13:38:201620 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011621 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381622
zmo9528c9f42015-08-04 22:12:081623 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011624 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381625
zmo9528c9f42015-08-04 22:12:081626 std::string response_data;
bnc691fda62016-08-12 00:43:161627 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011628 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081629 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381630}
1631
bncd16676a2016-07-20 16:23:011632TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381633 HttpRequestInfo request;
1634 request.method = "POST";
1635 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101636 request.traffic_annotation =
1637 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381638
danakj1fd259a02016-04-16 03:17:091639 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161640 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271641
[email protected]ee9410e72010-01-07 01:42:381642 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061643 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381644 };
Ryan Sleevib8d7ea02018-05-07 20:01:011645 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071646 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381647
[email protected]49639fa2011-12-20 23:22:411648 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381649
tfarina42834112016-09-22 13:38:201650 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381652
1653 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011654 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381655}
1656
[email protected]23e482282013-06-14 16:08:021657void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511658 const MockWrite* write_failure,
1659 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421660 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521661 request.method = "GET";
1662 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101663 request.traffic_annotation =
1664 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521665
vishal.b62985ca92015-04-17 08:45:511666 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071667 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091668 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271669
[email protected]202965992011-12-07 23:04:511670 // Written data for successfully sending both requests.
1671 MockWrite data1_writes[] = {
1672 MockWrite("GET / HTTP/1.1\r\n"
1673 "Host: www.foo.com\r\n"
1674 "Connection: keep-alive\r\n\r\n"),
1675 MockWrite("GET / HTTP/1.1\r\n"
1676 "Host: www.foo.com\r\n"
1677 "Connection: keep-alive\r\n\r\n")
1678 };
1679
1680 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521681 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351682 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1683 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061684 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521685 };
[email protected]202965992011-12-07 23:04:511686
1687 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491688 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511689 data1_writes[1] = *write_failure;
1690 } else {
1691 ASSERT_TRUE(read_failure);
1692 data1_reads[2] = *read_failure;
1693 }
1694
Ryan Sleevib8d7ea02018-05-07 20:01:011695 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]bb88e1d32013-05-03 23:11:071696 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521697
1698 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351699 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1700 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061701 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521702 };
Ryan Sleevib8d7ea02018-05-07 20:01:011703 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071704 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521705
thestig9d3bb0c2015-01-24 00:49:511706 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521707 "hello", "world"
1708 };
1709
mikecironef22f9812016-10-04 03:40:191710 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521711 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411712 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521713
bnc691fda62016-08-12 00:43:161714 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521715
tfarina42834112016-09-22 13:38:201716 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011717 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521718
1719 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011720 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521721
[email protected]58e32bb2013-01-21 18:23:251722 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161723 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251724 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1725 if (i == 0) {
1726 first_socket_log_id = load_timing_info.socket_log_id;
1727 } else {
1728 // The second request should be using a new socket.
1729 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1730 }
1731
bnc691fda62016-08-12 00:43:161732 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521733 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521734
wezca1070932016-05-26 20:30:521735 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471736 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251737 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521738
1739 std::string response_data;
bnc691fda62016-08-12 00:43:161740 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011741 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251742 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521743 }
1744}
[email protected]3d2a59b2008-09-26 19:44:251745
[email protected]a34f61ee2014-03-18 20:59:491746void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1747 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101748 const MockRead* read_failure,
1749 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491750 HttpRequestInfo request;
1751 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101752 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101753 request.traffic_annotation =
1754 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491755
vishal.b62985ca92015-04-17 08:45:511756 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491757 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491759
[email protected]09356c652014-03-25 15:36:101760 SSLSocketDataProvider ssl1(ASYNC, OK);
1761 SSLSocketDataProvider ssl2(ASYNC, OK);
1762 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361763 ssl1.next_proto = kProtoHTTP2;
1764 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101765 }
1766 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1767 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491768
[email protected]09356c652014-03-25 15:36:101769 // SPDY versions of the request and response.
Ryan Hamilton0239aac2018-05-19 00:03:131770 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491771 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131772 spdy::SpdySerializedFrame spdy_response(
Raul Tambre94493c652019-03-11 17:18:351773 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131774 spdy::SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191775 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491776
[email protected]09356c652014-03-25 15:36:101777 // HTTP/1.1 versions of the request and response.
1778 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1779 "Host: www.foo.com\r\n"
1780 "Connection: keep-alive\r\n\r\n";
1781 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1782 const char kHttpData[] = "hello";
1783
1784 std::vector<MockRead> data1_reads;
1785 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491786 if (write_failure) {
1787 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101788 data1_writes.push_back(*write_failure);
1789 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491790 } else {
1791 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101792 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411793 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101794 } else {
1795 data1_writes.push_back(MockWrite(kHttpRequest));
1796 }
1797 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491798 }
1799
Ryan Sleevib8d7ea02018-05-07 20:01:011800 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]a34f61ee2014-03-18 20:59:491801 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1802
[email protected]09356c652014-03-25 15:36:101803 std::vector<MockRead> data2_reads;
1804 std::vector<MockWrite> data2_writes;
1805
1806 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411807 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101808
bncdf80d44fd2016-07-15 20:27:411809 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1810 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101811 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1812 } else {
1813 data2_writes.push_back(
1814 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1815
1816 data2_reads.push_back(
1817 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1818 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1819 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1820 }
Ryan Sleevib8d7ea02018-05-07 20:01:011821 SequencedSocketData data2(data2_reads, data2_writes);
[email protected]a34f61ee2014-03-18 20:59:491822 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1823
1824 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591825 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491826 // Wait for the preconnect to complete.
1827 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1828 base::RunLoop().RunUntilIdle();
Matt Menke9d5e2c92019-02-05 01:42:231829 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491830
1831 // Make the request.
1832 TestCompletionCallback callback;
1833
bnc691fda62016-08-12 00:43:161834 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491835
tfarina42834112016-09-22 13:38:201836 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011837 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491838
1839 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011840 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491841
1842 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161843 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101844 TestLoadTimingNotReused(
1845 load_timing_info,
1846 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491847
bnc691fda62016-08-12 00:43:161848 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521849 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491850
wezca1070932016-05-26 20:30:521851 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021852 if (response->was_fetched_via_spdy) {
1853 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1854 } else {
1855 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1856 }
[email protected]a34f61ee2014-03-18 20:59:491857
1858 std::string response_data;
bnc691fda62016-08-12 00:43:161859 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011860 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101861 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491862}
1863
Biljith Jayan45a41722017-08-16 18:43:141864// Test that we do not retry indefinitely when a server sends an error like
1865// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1866// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1867TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1868 HttpRequestInfo request;
1869 request.method = "GET";
1870 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101871 request.traffic_annotation =
1872 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141873
1874 // Check whether we give up after the third try.
1875
1876 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131877 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141878 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131879 spdy::SpdySerializedFrame spdy_response_go_away(
1880 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011881 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1882 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141883
1884 // Three go away responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011885 StaticSocketDataProvider data1(data_read1, data_write);
1886 StaticSocketDataProvider data2(data_read1, data_write);
1887 StaticSocketDataProvider data3(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141888
1889 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1890 AddSSLSocketData();
1891 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1892 AddSSLSocketData();
1893 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1894 AddSSLSocketData();
1895
1896 TestCompletionCallback callback;
1897 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1898 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1899
1900 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1901 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1902
1903 rv = callback.WaitForResult();
1904 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1905}
1906
1907TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1908 HttpRequestInfo request;
1909 request.method = "GET";
1910 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101911 request.traffic_annotation =
1912 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141913
1914 // Check whether we try atleast thrice before giving up.
1915
1916 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131917 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141918 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131919 spdy::SpdySerializedFrame spdy_response_go_away(
1920 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011921 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1922 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141923
1924 // Construct a non error HTTP2 response.
Ryan Hamilton0239aac2018-05-19 00:03:131925 spdy::SpdySerializedFrame spdy_response_no_error(
Biljith Jayan45a41722017-08-16 18:43:141926 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131927 spdy::SpdySerializedFrame spdy_data(
1928 spdy_util_.ConstructSpdyDataFrame(1, true));
Biljith Jayan45a41722017-08-16 18:43:141929 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1930 CreateMockRead(spdy_data, 2)};
1931
1932 // Two error responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011933 StaticSocketDataProvider data1(data_read1, data_write);
1934 StaticSocketDataProvider data2(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141935 // Followed by a success response.
Ryan Sleevib8d7ea02018-05-07 20:01:011936 SequencedSocketData data3(data_read2, data_write);
Biljith Jayan45a41722017-08-16 18:43:141937
1938 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1939 AddSSLSocketData();
1940 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1941 AddSSLSocketData();
1942 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1943 AddSSLSocketData();
1944
1945 TestCompletionCallback callback;
1946 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1947 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1948
1949 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1950 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1951
1952 rv = callback.WaitForResult();
1953 EXPECT_THAT(rv, IsOk());
1954}
1955
bncd16676a2016-07-20 16:23:011956TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061957 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:351958 KeepAliveConnectionResendRequestTest(&write_failure, nullptr);
[email protected]202965992011-12-07 23:04:511959}
1960
bncd16676a2016-07-20 16:23:011961TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061962 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:351963 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251964}
1965
bncd16676a2016-07-20 16:23:011966TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061967 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351968 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251969}
1970
[email protected]d58ceea82014-06-04 10:55:541971// Make sure that on a 408 response (Request Timeout), the request is retried,
1972// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011973TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541974 MockRead read_failure(SYNCHRONOUS,
1975 "HTTP/1.1 408 Request Timeout\r\n"
1976 "Connection: Keep-Alive\r\n"
1977 "Content-Length: 6\r\n\r\n"
1978 "Pickle");
Raul Tambre94493c652019-03-11 17:18:351979 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]d58ceea82014-06-04 10:55:541980}
1981
bncd16676a2016-07-20 16:23:011982TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491983 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:351984 PreconnectErrorResendRequestTest(&write_failure, nullptr, false);
[email protected]a34f61ee2014-03-18 20:59:491985}
1986
bncd16676a2016-07-20 16:23:011987TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491988 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:351989 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491990}
1991
bncd16676a2016-07-20 16:23:011992TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491993 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351994 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]09356c652014-03-25 15:36:101995}
1996
bncd16676a2016-07-20 16:23:011997TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101998 MockRead read_failure(ASYNC, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351999 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]09356c652014-03-25 15:36:102000}
2001
[email protected]d58ceea82014-06-04 10:55:542002// Make sure that on a 408 response (Request Timeout), the request is retried,
2003// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:012004TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:542005 MockRead read_failure(SYNCHRONOUS,
2006 "HTTP/1.1 408 Request Timeout\r\n"
2007 "Connection: Keep-Alive\r\n"
2008 "Content-Length: 6\r\n\r\n"
2009 "Pickle");
Raul Tambre94493c652019-03-11 17:18:352010 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
2011 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]d58ceea82014-06-04 10:55:542012}
2013
bncd16676a2016-07-20 16:23:012014TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:102015 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:352016 PreconnectErrorResendRequestTest(&write_failure, nullptr, true);
[email protected]09356c652014-03-25 15:36:102017}
2018
bncd16676a2016-07-20 16:23:012019TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:102020 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:352021 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]09356c652014-03-25 15:36:102022}
2023
bncd16676a2016-07-20 16:23:012024TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:102025 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352026 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]09356c652014-03-25 15:36:102027}
2028
bncd16676a2016-07-20 16:23:012029TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:102030 MockRead read_failure(ASYNC, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352031 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:492032}
2033
bncd16676a2016-07-20 16:23:012034TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:422035 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:252036 request.method = "GET";
bncce36dca22015-04-21 22:11:232037 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102038 request.traffic_annotation =
2039 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:252040
danakj1fd259a02016-04-16 03:17:092041 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162042 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272043
[email protected]3d2a59b2008-09-26 19:44:252044 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062045 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:352046 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2047 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062048 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252049 };
Ryan Sleevib8d7ea02018-05-07 20:01:012050 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072051 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:252052
[email protected]49639fa2011-12-20 23:22:412053 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:252054
tfarina42834112016-09-22 13:38:202055 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012056 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:252057
2058 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012059 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:592060
2061 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162062 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592063 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:252064}
2065
2066// What do various browsers do when the server closes a non-keepalive
2067// connection without sending any response header or body?
2068//
2069// IE7: error page
2070// Safari 3.1.2 (Windows): error page
2071// Firefox 3.0.1: blank page
2072// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:422073// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
2074// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:012075TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:252076 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062077 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:352078 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2079 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062080 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252081 };
Ryan Sleevib8d7ea02018-05-07 20:01:012082 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:012083 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:252084}
[email protected]1826a402014-01-08 15:40:482085
[email protected]7a5378b2012-11-04 03:25:172086// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
2087// tests. There was a bug causing HttpNetworkTransaction to hang in the
2088// destructor in such situations.
2089// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:012090TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:172091 HttpRequestInfo request;
2092 request.method = "GET";
bncce36dca22015-04-21 22:11:232093 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102094 request.traffic_annotation =
2095 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172096
danakj1fd259a02016-04-16 03:17:092097 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582098 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192099 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172100
2101 MockRead data_reads[] = {
2102 MockRead("HTTP/1.0 200 OK\r\n"),
2103 MockRead("Connection: keep-alive\r\n"),
2104 MockRead("Content-Length: 100\r\n\r\n"),
2105 MockRead("hello"),
2106 MockRead(SYNCHRONOUS, 0),
2107 };
Ryan Sleevib8d7ea02018-05-07 20:01:012108 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072109 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172110
2111 TestCompletionCallback callback;
2112
tfarina42834112016-09-22 13:38:202113 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172115
2116 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012117 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172118
Victor Costan9c7302b2018-08-27 16:39:442119 scoped_refptr<IOBufferWithSize> io_buf =
2120 base::MakeRefCounted<IOBufferWithSize>(100);
[email protected]90499482013-06-01 00:39:502121 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172122 if (rv == ERR_IO_PENDING)
2123 rv = callback.WaitForResult();
2124 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:502125 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:012126 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172127
2128 trans.reset();
fdoray92e35a72016-06-10 15:54:552129 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172130 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2131}
2132
bncd16676a2016-07-20 16:23:012133TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:172134 HttpRequestInfo request;
2135 request.method = "GET";
bncce36dca22015-04-21 22:11:232136 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102137 request.traffic_annotation =
2138 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172139
danakj1fd259a02016-04-16 03:17:092140 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582141 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192142 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172143
2144 MockRead data_reads[] = {
2145 MockRead("HTTP/1.0 200 OK\r\n"),
2146 MockRead("Connection: keep-alive\r\n"),
2147 MockRead("Content-Length: 100\r\n\r\n"),
2148 MockRead(SYNCHRONOUS, 0),
2149 };
Ryan Sleevib8d7ea02018-05-07 20:01:012150 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072151 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172152
2153 TestCompletionCallback callback;
2154
tfarina42834112016-09-22 13:38:202155 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012156 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172157
2158 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012159 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172160
Victor Costan9c7302b2018-08-27 16:39:442161 scoped_refptr<IOBufferWithSize> io_buf(
2162 base::MakeRefCounted<IOBufferWithSize>(100));
[email protected]90499482013-06-01 00:39:502163 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172164 if (rv == ERR_IO_PENDING)
2165 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012166 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172167
2168 trans.reset();
fdoray92e35a72016-06-10 15:54:552169 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172170 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2171}
2172
[email protected]0b0bf032010-09-21 18:08:502173// Test that we correctly reuse a keep-alive connection after not explicitly
2174// reading the body.
bncd16676a2016-07-20 16:23:012175TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132176 HttpRequestInfo request;
2177 request.method = "GET";
2178 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102179 request.traffic_annotation =
2180 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132181
vishal.b62985ca92015-04-17 08:45:512182 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072183 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092184 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272185
mmenkecc2298e2015-12-07 18:20:182186 const char* request_data =
2187 "GET / HTTP/1.1\r\n"
2188 "Host: www.foo.com\r\n"
2189 "Connection: keep-alive\r\n\r\n";
2190 MockWrite data_writes[] = {
2191 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2192 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2193 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2194 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2195 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2196 };
2197
[email protected]0b0bf032010-09-21 18:08:502198 // Note that because all these reads happen in the same
2199 // StaticSocketDataProvider, it shows that the same socket is being reused for
2200 // all transactions.
mmenkecc2298e2015-12-07 18:20:182201 MockRead data_reads[] = {
2202 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2203 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2204 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2205 MockRead(ASYNC, 7,
2206 "HTTP/1.1 302 Found\r\n"
2207 "Content-Length: 0\r\n\r\n"),
2208 MockRead(ASYNC, 9,
2209 "HTTP/1.1 302 Found\r\n"
2210 "Content-Length: 5\r\n\r\n"
2211 "hello"),
2212 MockRead(ASYNC, 11,
2213 "HTTP/1.1 301 Moved Permanently\r\n"
2214 "Content-Length: 0\r\n\r\n"),
2215 MockRead(ASYNC, 13,
2216 "HTTP/1.1 301 Moved Permanently\r\n"
2217 "Content-Length: 5\r\n\r\n"
2218 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132219
mmenkecc2298e2015-12-07 18:20:182220 // In the next two rounds, IsConnectedAndIdle returns false, due to
2221 // the set_busy_before_sync_reads(true) call, while the
2222 // HttpNetworkTransaction is being shut down, but the socket is still
2223 // reuseable. See http://crbug.com/544255.
2224 MockRead(ASYNC, 15,
2225 "HTTP/1.1 200 Hunky-Dory\r\n"
2226 "Content-Length: 5\r\n\r\n"),
2227 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132228
mmenkecc2298e2015-12-07 18:20:182229 MockRead(ASYNC, 18,
2230 "HTTP/1.1 200 Hunky-Dory\r\n"
2231 "Content-Length: 5\r\n\r\n"
2232 "he"),
2233 MockRead(SYNCHRONOUS, 19, "llo"),
2234
2235 // The body of the final request is actually read.
2236 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2237 MockRead(ASYNC, 22, "hello"),
2238 };
Ryan Sleevib8d7ea02018-05-07 20:01:012239 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182240 data.set_busy_before_sync_reads(true);
2241 session_deps_.socket_factory->AddSocketDataProvider(&data);
2242
Avi Drissman4365a4782018-12-28 19:26:242243 const int kNumUnreadBodies = base::size(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502244 std::string response_lines[kNumUnreadBodies];
2245
mikecironef22f9812016-10-04 03:40:192246 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182247 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412248 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132249
Jeremy Roman0579ed62017-08-29 15:56:192250 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582251 session.get());
[email protected]fc31d6a42010-06-24 18:05:132252
tfarina42834112016-09-22 13:38:202253 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012254 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132255
[email protected]58e32bb2013-01-21 18:23:252256 LoadTimingInfo load_timing_info;
2257 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2258 if (i == 0) {
2259 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2260 first_socket_log_id = load_timing_info.socket_log_id;
2261 } else {
2262 TestLoadTimingReused(load_timing_info);
2263 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2264 }
2265
[email protected]fc31d6a42010-06-24 18:05:132266 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182267 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132268
mmenkecc2298e2015-12-07 18:20:182269 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502270 response_lines[i] = response->headers->GetStatusLine();
2271
mmenkecc2298e2015-12-07 18:20:182272 // Delete the transaction without reading the response bodies. Then spin
2273 // the message loop, so the response bodies are drained.
2274 trans.reset();
2275 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132276 }
[email protected]0b0bf032010-09-21 18:08:502277
2278 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182279 "HTTP/1.1 204 No Content",
2280 "HTTP/1.1 205 Reset Content",
2281 "HTTP/1.1 304 Not Modified",
2282 "HTTP/1.1 302 Found",
2283 "HTTP/1.1 302 Found",
2284 "HTTP/1.1 301 Moved Permanently",
2285 "HTTP/1.1 301 Moved Permanently",
2286 "HTTP/1.1 200 Hunky-Dory",
2287 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502288 };
2289
Avi Drissman4365a4782018-12-28 19:26:242290 static_assert(kNumUnreadBodies == base::size(kStatusLines),
mostynb91e0da982015-01-20 19:17:272291 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502292
2293 for (int i = 0; i < kNumUnreadBodies; ++i)
2294 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2295
[email protected]49639fa2011-12-20 23:22:412296 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162297 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202298 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012299 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162300 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182301 ASSERT_TRUE(response);
2302 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502303 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2304 std::string response_data;
bnc691fda62016-08-12 00:43:162305 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012306 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502307 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132308}
2309
mmenke5f94fda2016-06-02 20:54:132310// Sockets that receive extra data after a response is complete should not be
2311// reused.
bncd16676a2016-07-20 16:23:012312TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132313 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2314 MockWrite data_writes1[] = {
2315 MockWrite("HEAD / HTTP/1.1\r\n"
2316 "Host: www.borked.com\r\n"
2317 "Connection: keep-alive\r\n\r\n"),
2318 };
2319
2320 MockRead data_reads1[] = {
2321 MockRead("HTTP/1.1 200 OK\r\n"
2322 "Connection: keep-alive\r\n"
2323 "Content-Length: 22\r\n\r\n"
2324 "This server is borked."),
2325 };
2326
2327 MockWrite data_writes2[] = {
2328 MockWrite("GET /foo HTTP/1.1\r\n"
2329 "Host: www.borked.com\r\n"
2330 "Connection: keep-alive\r\n\r\n"),
2331 };
2332
2333 MockRead data_reads2[] = {
2334 MockRead("HTTP/1.1 200 OK\r\n"
2335 "Content-Length: 3\r\n\r\n"
2336 "foo"),
2337 };
Ryan Sleevib8d7ea02018-05-07 20:01:012338 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132339 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012340 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132341 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2342
2343 TestCompletionCallback callback;
2344 HttpRequestInfo request1;
2345 request1.method = "HEAD";
2346 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102347 request1.traffic_annotation =
2348 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132349
bnc87dcefc2017-05-25 12:47:582350 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192351 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202352 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012353 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132354
2355 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2356 ASSERT_TRUE(response1);
2357 ASSERT_TRUE(response1->headers);
2358 EXPECT_EQ(200, response1->headers->response_code());
2359 EXPECT_TRUE(response1->headers->IsKeepAlive());
2360
2361 std::string response_data1;
robpercival214763f2016-07-01 23:27:012362 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132363 EXPECT_EQ("", response_data1);
2364 // Deleting the transaction attempts to release the socket back into the
2365 // socket pool.
2366 trans1.reset();
2367
2368 HttpRequestInfo request2;
2369 request2.method = "GET";
2370 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102371 request2.traffic_annotation =
2372 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132373
bnc87dcefc2017-05-25 12:47:582374 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192375 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202376 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012377 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132378
2379 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2380 ASSERT_TRUE(response2);
2381 ASSERT_TRUE(response2->headers);
2382 EXPECT_EQ(200, response2->headers->response_code());
2383
2384 std::string response_data2;
robpercival214763f2016-07-01 23:27:012385 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132386 EXPECT_EQ("foo", response_data2);
2387}
2388
bncd16676a2016-07-20 16:23:012389TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132390 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2391 MockWrite data_writes1[] = {
2392 MockWrite("GET / HTTP/1.1\r\n"
2393 "Host: www.borked.com\r\n"
2394 "Connection: keep-alive\r\n\r\n"),
2395 };
2396
2397 MockRead data_reads1[] = {
2398 MockRead("HTTP/1.1 200 OK\r\n"
2399 "Connection: keep-alive\r\n"
2400 "Content-Length: 22\r\n\r\n"
2401 "This server is borked."
2402 "Bonus data!"),
2403 };
2404
2405 MockWrite data_writes2[] = {
2406 MockWrite("GET /foo HTTP/1.1\r\n"
2407 "Host: www.borked.com\r\n"
2408 "Connection: keep-alive\r\n\r\n"),
2409 };
2410
2411 MockRead data_reads2[] = {
2412 MockRead("HTTP/1.1 200 OK\r\n"
2413 "Content-Length: 3\r\n\r\n"
2414 "foo"),
2415 };
Ryan Sleevib8d7ea02018-05-07 20:01:012416 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132417 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012418 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132419 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2420
2421 TestCompletionCallback callback;
2422 HttpRequestInfo request1;
2423 request1.method = "GET";
2424 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102425 request1.traffic_annotation =
2426 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132427
bnc87dcefc2017-05-25 12:47:582428 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192429 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202430 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012431 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132432
2433 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2434 ASSERT_TRUE(response1);
2435 ASSERT_TRUE(response1->headers);
2436 EXPECT_EQ(200, response1->headers->response_code());
2437 EXPECT_TRUE(response1->headers->IsKeepAlive());
2438
2439 std::string response_data1;
robpercival214763f2016-07-01 23:27:012440 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132441 EXPECT_EQ("This server is borked.", response_data1);
2442 // Deleting the transaction attempts to release the socket back into the
2443 // socket pool.
2444 trans1.reset();
2445
2446 HttpRequestInfo request2;
2447 request2.method = "GET";
2448 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102449 request2.traffic_annotation =
2450 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132451
bnc87dcefc2017-05-25 12:47:582452 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192453 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202454 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012455 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132456
2457 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2458 ASSERT_TRUE(response2);
2459 ASSERT_TRUE(response2->headers);
2460 EXPECT_EQ(200, response2->headers->response_code());
2461
2462 std::string response_data2;
robpercival214763f2016-07-01 23:27:012463 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132464 EXPECT_EQ("foo", response_data2);
2465}
2466
bncd16676a2016-07-20 16:23:012467TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132468 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2469 MockWrite data_writes1[] = {
2470 MockWrite("GET / HTTP/1.1\r\n"
2471 "Host: www.borked.com\r\n"
2472 "Connection: keep-alive\r\n\r\n"),
2473 };
2474
2475 MockRead data_reads1[] = {
2476 MockRead("HTTP/1.1 200 OK\r\n"
2477 "Connection: keep-alive\r\n"
2478 "Transfer-Encoding: chunked\r\n\r\n"),
2479 MockRead("16\r\nThis server is borked.\r\n"),
2480 MockRead("0\r\n\r\nBonus data!"),
2481 };
2482
2483 MockWrite data_writes2[] = {
2484 MockWrite("GET /foo HTTP/1.1\r\n"
2485 "Host: www.borked.com\r\n"
2486 "Connection: keep-alive\r\n\r\n"),
2487 };
2488
2489 MockRead data_reads2[] = {
2490 MockRead("HTTP/1.1 200 OK\r\n"
2491 "Content-Length: 3\r\n\r\n"
2492 "foo"),
2493 };
Ryan Sleevib8d7ea02018-05-07 20:01:012494 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132495 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012496 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132497 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2498
2499 TestCompletionCallback callback;
2500 HttpRequestInfo request1;
2501 request1.method = "GET";
2502 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102503 request1.traffic_annotation =
2504 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132505
bnc87dcefc2017-05-25 12:47:582506 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192507 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202508 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012509 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132510
2511 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2512 ASSERT_TRUE(response1);
2513 ASSERT_TRUE(response1->headers);
2514 EXPECT_EQ(200, response1->headers->response_code());
2515 EXPECT_TRUE(response1->headers->IsKeepAlive());
2516
2517 std::string response_data1;
robpercival214763f2016-07-01 23:27:012518 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132519 EXPECT_EQ("This server is borked.", response_data1);
2520 // Deleting the transaction attempts to release the socket back into the
2521 // socket pool.
2522 trans1.reset();
2523
2524 HttpRequestInfo request2;
2525 request2.method = "GET";
2526 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102527 request2.traffic_annotation =
2528 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132529
bnc87dcefc2017-05-25 12:47:582530 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192531 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202532 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012533 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132534
2535 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2536 ASSERT_TRUE(response2);
2537 ASSERT_TRUE(response2->headers);
2538 EXPECT_EQ(200, response2->headers->response_code());
2539
2540 std::string response_data2;
robpercival214763f2016-07-01 23:27:012541 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132542 EXPECT_EQ("foo", response_data2);
2543}
2544
2545// This is a little different from the others - it tests the case that the
2546// HttpStreamParser doesn't know if there's extra data on a socket or not when
2547// the HttpNetworkTransaction is torn down, because the response body hasn't
2548// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012549TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132550 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2551 MockWrite data_writes1[] = {
2552 MockWrite("GET / HTTP/1.1\r\n"
2553 "Host: www.borked.com\r\n"
2554 "Connection: keep-alive\r\n\r\n"),
2555 };
2556
2557 MockRead data_reads1[] = {
2558 MockRead("HTTP/1.1 200 OK\r\n"
2559 "Connection: keep-alive\r\n"
2560 "Transfer-Encoding: chunked\r\n\r\n"),
2561 MockRead("16\r\nThis server is borked.\r\n"),
2562 MockRead("0\r\n\r\nBonus data!"),
2563 };
Ryan Sleevib8d7ea02018-05-07 20:01:012564 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132565 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2566
2567 TestCompletionCallback callback;
2568 HttpRequestInfo request1;
2569 request1.method = "GET";
2570 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102571 request1.traffic_annotation =
2572 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132573
bnc87dcefc2017-05-25 12:47:582574 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192575 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582576 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012577 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132578
bnc87dcefc2017-05-25 12:47:582579 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132580 ASSERT_TRUE(response1);
2581 ASSERT_TRUE(response1->headers);
2582 EXPECT_EQ(200, response1->headers->response_code());
2583 EXPECT_TRUE(response1->headers->IsKeepAlive());
2584
2585 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2586 // response body.
bnc87dcefc2017-05-25 12:47:582587 trans.reset();
mmenke5f94fda2016-06-02 20:54:132588
2589 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2590 // socket can't be reused, rather than returning it to the socket pool.
2591 base::RunLoop().RunUntilIdle();
2592
2593 // There should be no idle sockets in the pool.
2594 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2595}
2596
[email protected]038e9a32008-10-08 22:40:162597// Test the request-challenge-retry sequence for basic auth.
2598// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012599TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422600 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162601 request.method = "GET";
bncce36dca22015-04-21 22:11:232602 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102603 request.traffic_annotation =
2604 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162605
vishal.b62985ca92015-04-17 08:45:512606 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072607 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092608 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162609 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272610
[email protected]f9ee6b52008-11-08 06:46:232611 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232612 MockWrite(
2613 "GET / HTTP/1.1\r\n"
2614 "Host: www.example.org\r\n"
2615 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232616 };
2617
[email protected]038e9a32008-10-08 22:40:162618 MockRead data_reads1[] = {
2619 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2620 // Give a couple authenticate options (only the middle one is actually
2621 // supported).
[email protected]22927ad2009-09-21 19:56:192622 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162623 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2624 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2625 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2626 // Large content-length -- won't matter, as connection will be reset.
2627 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062628 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162629 };
2630
2631 // After calling trans->RestartWithAuth(), this is the request we should
2632 // be issuing -- the final header line contains the credentials.
2633 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232634 MockWrite(
2635 "GET / HTTP/1.1\r\n"
2636 "Host: www.example.org\r\n"
2637 "Connection: keep-alive\r\n"
2638 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162639 };
2640
2641 // Lastly, the server responds with the actual content.
2642 MockRead data_reads2[] = {
2643 MockRead("HTTP/1.0 200 OK\r\n"),
2644 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2645 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062646 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162647 };
2648
Ryan Sleevib8d7ea02018-05-07 20:01:012649 StaticSocketDataProvider data1(data_reads1, data_writes1);
2650 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072651 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2652 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162653
[email protected]49639fa2011-12-20 23:22:412654 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162655
tfarina42834112016-09-22 13:38:202656 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012657 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162658
2659 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012660 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162661
[email protected]58e32bb2013-01-21 18:23:252662 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162663 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252664 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2665
Ryan Sleevib8d7ea02018-05-07 20:01:012666 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162667 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012668 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162669 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192670
bnc691fda62016-08-12 00:43:162671 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522672 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582673 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]038e9a32008-10-08 22:40:162674
[email protected]49639fa2011-12-20 23:22:412675 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162676
bnc691fda62016-08-12 00:43:162677 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012678 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162679
2680 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012681 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162682
[email protected]58e32bb2013-01-21 18:23:252683 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162684 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252685 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2686 // The load timing after restart should have a new socket ID, and times after
2687 // those of the first load timing.
2688 EXPECT_LE(load_timing_info1.receive_headers_end,
2689 load_timing_info2.connect_timing.connect_start);
2690 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2691
Ryan Sleevib8d7ea02018-05-07 20:01:012692 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162693 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012694 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162695 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192696
bnc691fda62016-08-12 00:43:162697 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522698 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582699 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]038e9a32008-10-08 22:40:162700 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162701}
2702
ttuttled9dbc652015-09-29 20:00:592703// Test the request-challenge-retry sequence for basic auth.
2704// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012705TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592706 HttpRequestInfo request;
2707 request.method = "GET";
2708 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102709 request.traffic_annotation =
2710 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592711
2712 TestNetLog log;
2713 MockHostResolver* resolver = new MockHostResolver();
2714 session_deps_.net_log = &log;
2715 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092716 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592718
2719 resolver->rules()->ClearRules();
2720 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2721
2722 MockWrite data_writes1[] = {
2723 MockWrite("GET / HTTP/1.1\r\n"
2724 "Host: www.example.org\r\n"
2725 "Connection: keep-alive\r\n\r\n"),
2726 };
2727
2728 MockRead data_reads1[] = {
2729 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2730 // Give a couple authenticate options (only the middle one is actually
2731 // supported).
2732 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2733 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2734 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2735 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2736 // Large content-length -- won't matter, as connection will be reset.
2737 MockRead("Content-Length: 10000\r\n\r\n"),
2738 MockRead(SYNCHRONOUS, ERR_FAILED),
2739 };
2740
2741 // After calling trans->RestartWithAuth(), this is the request we should
2742 // be issuing -- the final header line contains the credentials.
2743 MockWrite data_writes2[] = {
2744 MockWrite("GET / HTTP/1.1\r\n"
2745 "Host: www.example.org\r\n"
2746 "Connection: keep-alive\r\n"
2747 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2748 };
2749
2750 // Lastly, the server responds with the actual content.
2751 MockRead data_reads2[] = {
2752 MockRead("HTTP/1.0 200 OK\r\n"),
2753 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2754 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2755 };
2756
Ryan Sleevib8d7ea02018-05-07 20:01:012757 StaticSocketDataProvider data1(data_reads1, data_writes1);
2758 StaticSocketDataProvider data2(data_reads2, data_writes2);
ttuttled9dbc652015-09-29 20:00:592759 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2760 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2761
2762 TestCompletionCallback callback1;
2763
bnc691fda62016-08-12 00:43:162764 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202765 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592766
2767 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162768 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592769 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2770
Ryan Sleevib8d7ea02018-05-07 20:01:012771 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162772 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012773 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162774 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592775
bnc691fda62016-08-12 00:43:162776 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592777 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582778 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
ttuttled9dbc652015-09-29 20:00:592779
2780 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162781 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592782 ASSERT_FALSE(endpoint.address().empty());
2783 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2784
2785 resolver->rules()->ClearRules();
2786 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2787
2788 TestCompletionCallback callback2;
2789
bnc691fda62016-08-12 00:43:162790 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592791 AuthCredentials(kFoo, kBar), callback2.callback())));
2792
2793 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162794 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592795 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2796 // The load timing after restart should have a new socket ID, and times after
2797 // those of the first load timing.
2798 EXPECT_LE(load_timing_info1.receive_headers_end,
2799 load_timing_info2.connect_timing.connect_start);
2800 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2801
Ryan Sleevib8d7ea02018-05-07 20:01:012802 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162803 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012804 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162805 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592806
bnc691fda62016-08-12 00:43:162807 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592808 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582809 EXPECT_FALSE(response->auth_challenge.has_value());
ttuttled9dbc652015-09-29 20:00:592810 EXPECT_EQ(100, response->headers->GetContentLength());
2811
bnc691fda62016-08-12 00:43:162812 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592813 ASSERT_FALSE(endpoint.address().empty());
2814 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2815}
2816
David Benjamin83ddfb32018-03-30 01:07:522817// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2818// will eventually give up.
2819TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2820 HttpRequestInfo request;
2821 request.method = "GET";
2822 request.url = GURL("http://www.example.org/");
2823 request.traffic_annotation =
2824 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2825
2826 TestNetLog log;
2827 session_deps_.net_log = &log;
2828 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2829 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2830
2831 MockWrite data_writes[] = {
2832 MockWrite("GET / HTTP/1.1\r\n"
2833 "Host: www.example.org\r\n"
2834 "Connection: keep-alive\r\n\r\n"),
2835 };
2836
2837 MockRead data_reads[] = {
2838 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2839 // Give a couple authenticate options (only the middle one is actually
2840 // supported).
2841 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2842 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2843 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2844 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2845 // Large content-length -- won't matter, as connection will be reset.
2846 MockRead("Content-Length: 10000\r\n\r\n"),
2847 MockRead(SYNCHRONOUS, ERR_FAILED),
2848 };
2849
2850 // After calling trans->RestartWithAuth(), this is the request we should
2851 // be issuing -- the final header line contains the credentials.
2852 MockWrite data_writes_restart[] = {
2853 MockWrite("GET / HTTP/1.1\r\n"
2854 "Host: www.example.org\r\n"
2855 "Connection: keep-alive\r\n"
2856 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2857 };
2858
Ryan Sleevib8d7ea02018-05-07 20:01:012859 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin83ddfb32018-03-30 01:07:522860 session_deps_.socket_factory->AddSocketDataProvider(&data);
2861
2862 TestCompletionCallback callback;
2863 int rv = callback.GetResult(
2864 trans.Start(&request, callback.callback(), NetLogWithSource()));
2865
2866 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2867 for (int i = 0; i < 32; i++) {
2868 // Check the previous response was a 401.
2869 EXPECT_THAT(rv, IsOk());
2870 const HttpResponseInfo* response = trans.GetResponseInfo();
2871 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582872 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
David Benjamin83ddfb32018-03-30 01:07:522873
2874 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:012875 data_reads, data_writes_restart));
David Benjamin83ddfb32018-03-30 01:07:522876 session_deps_.socket_factory->AddSocketDataProvider(
2877 data_restarts.back().get());
2878 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2879 callback.callback()));
2880 }
2881
2882 // After too many tries, the transaction should have given up.
2883 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2884}
2885
bncd16676a2016-07-20 16:23:012886TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462887 HttpRequestInfo request;
2888 request.method = "GET";
bncce36dca22015-04-21 22:11:232889 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292890 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:102891 request.traffic_annotation =
2892 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462893
danakj1fd259a02016-04-16 03:17:092894 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162895 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272896
[email protected]861fcd52009-08-26 02:33:462897 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232898 MockWrite(
2899 "GET / HTTP/1.1\r\n"
2900 "Host: www.example.org\r\n"
2901 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462902 };
2903
2904 MockRead data_reads[] = {
2905 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2906 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2907 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2908 // Large content-length -- won't matter, as connection will be reset.
2909 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062910 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462911 };
2912
Ryan Sleevib8d7ea02018-05-07 20:01:012913 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:072914 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412915 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462916
tfarina42834112016-09-22 13:38:202917 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012918 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462919
2920 rv = callback.WaitForResult();
2921 EXPECT_EQ(0, rv);
2922
Ryan Sleevib8d7ea02018-05-07 20:01:012923 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162924 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012925 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162926 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192927
bnc691fda62016-08-12 00:43:162928 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522929 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582930 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]861fcd52009-08-26 02:33:462931}
2932
[email protected]2d2697f92009-02-18 21:00:322933// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2934// connection.
bncd16676a2016-07-20 16:23:012935TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182936 // On the second pass, the body read of the auth challenge is synchronous, so
2937 // IsConnectedAndIdle returns false. The socket should still be drained and
2938 // reused. See http://crbug.com/544255.
2939 for (int i = 0; i < 2; ++i) {
2940 HttpRequestInfo request;
2941 request.method = "GET";
2942 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102943 request.traffic_annotation =
2944 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322945
mmenkecc2298e2015-12-07 18:20:182946 TestNetLog log;
2947 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092948 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272949
mmenkecc2298e2015-12-07 18:20:182950 MockWrite data_writes[] = {
2951 MockWrite(ASYNC, 0,
2952 "GET / HTTP/1.1\r\n"
2953 "Host: www.example.org\r\n"
2954 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322955
bnc691fda62016-08-12 00:43:162956 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182957 // be issuing -- the final header line contains the credentials.
2958 MockWrite(ASYNC, 6,
2959 "GET / HTTP/1.1\r\n"
2960 "Host: www.example.org\r\n"
2961 "Connection: keep-alive\r\n"
2962 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2963 };
[email protected]2d2697f92009-02-18 21:00:322964
mmenkecc2298e2015-12-07 18:20:182965 MockRead data_reads[] = {
2966 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2967 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2968 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2969 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2970 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322971
mmenkecc2298e2015-12-07 18:20:182972 // Lastly, the server responds with the actual content.
2973 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2974 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2975 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2976 MockRead(ASYNC, 10, "Hello"),
2977 };
[email protected]2d2697f92009-02-18 21:00:322978
Ryan Sleevib8d7ea02018-05-07 20:01:012979 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182980 data.set_busy_before_sync_reads(true);
2981 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462982
mmenkecc2298e2015-12-07 18:20:182983 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322984
bnc691fda62016-08-12 00:43:162985 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202986 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012987 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322988
mmenkecc2298e2015-12-07 18:20:182989 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162990 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182991 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322992
bnc691fda62016-08-12 00:43:162993 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182994 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582995 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]2d2697f92009-02-18 21:00:322996
mmenkecc2298e2015-12-07 18:20:182997 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252998
bnc691fda62016-08-12 00:43:162999 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
3000 callback2.callback());
robpercival214763f2016-07-01 23:27:013001 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323002
mmenkecc2298e2015-12-07 18:20:183003 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:163004 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:183005 TestLoadTimingReused(load_timing_info2);
3006 // The load timing after restart should have the same socket ID, and times
3007 // those of the first load timing.
3008 EXPECT_LE(load_timing_info1.receive_headers_end,
3009 load_timing_info2.send_start);
3010 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:323011
bnc691fda62016-08-12 00:43:163012 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:183013 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583014 EXPECT_FALSE(response->auth_challenge.has_value());
mmenkecc2298e2015-12-07 18:20:183015 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323016
mmenkecc2298e2015-12-07 18:20:183017 std::string response_data;
bnc691fda62016-08-12 00:43:163018 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:323019
Ryan Sleevib8d7ea02018-05-07 20:01:013020 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:163021 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:013022 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:163023 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:183024 }
[email protected]2d2697f92009-02-18 21:00:323025}
3026
3027// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3028// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:013029TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:423030 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323031 request.method = "GET";
bncce36dca22015-04-21 22:11:233032 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103033 request.traffic_annotation =
3034 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323035
danakj1fd259a02016-04-16 03:17:093036 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273037
[email protected]2d2697f92009-02-18 21:00:323038 MockWrite data_writes1[] = {
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\r\n"),
[email protected]2d2697f92009-02-18 21:00:323042
bnc691fda62016-08-12 00:43:163043 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233044 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163045 MockWrite("GET / HTTP/1.1\r\n"
3046 "Host: www.example.org\r\n"
3047 "Connection: keep-alive\r\n"
3048 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323049 };
3050
[email protected]2d2697f92009-02-18 21:00:323051 MockRead data_reads1[] = {
3052 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3053 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:313054 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:323055
3056 // Lastly, the server responds with the actual content.
3057 MockRead("HTTP/1.1 200 OK\r\n"),
3058 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503059 MockRead("Content-Length: 5\r\n\r\n"),
3060 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323061 };
3062
[email protected]2d0a4f92011-05-05 16:38:463063 // An incorrect reconnect would cause this to be read.
3064 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063065 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463066 };
3067
Ryan Sleevib8d7ea02018-05-07 20:01:013068 StaticSocketDataProvider data1(data_reads1, data_writes1);
3069 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073070 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3071 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323072
[email protected]49639fa2011-12-20 23:22:413073 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323074
bnc691fda62016-08-12 00:43:163075 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203076 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013077 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323078
3079 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013080 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323081
bnc691fda62016-08-12 00:43:163082 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523083 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583084 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]2d2697f92009-02-18 21:00:323085
[email protected]49639fa2011-12-20 23:22:413086 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323087
bnc691fda62016-08-12 00:43:163088 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013089 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323090
3091 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013092 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323093
bnc691fda62016-08-12 00:43:163094 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523095 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583096 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0b0bf032010-09-21 18:08:503097 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323098}
3099
3100// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3101// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:013102TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:423103 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323104 request.method = "GET";
bncce36dca22015-04-21 22:11:233105 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103106 request.traffic_annotation =
3107 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323108
danakj1fd259a02016-04-16 03:17:093109 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273110
[email protected]2d2697f92009-02-18 21:00:323111 MockWrite data_writes1[] = {
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\r\n"),
[email protected]2d2697f92009-02-18 21:00:323115
bnc691fda62016-08-12 00:43:163116 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233117 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163118 MockWrite("GET / HTTP/1.1\r\n"
3119 "Host: www.example.org\r\n"
3120 "Connection: keep-alive\r\n"
3121 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323122 };
3123
3124 // Respond with 5 kb of response body.
3125 std::string large_body_string("Unauthorized");
3126 large_body_string.append(5 * 1024, ' ');
3127 large_body_string.append("\r\n");
3128
3129 MockRead data_reads1[] = {
3130 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3131 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3132 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3133 // 5134 = 12 + 5 * 1024 + 2
3134 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063135 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:323136
3137 // Lastly, the server responds with the actual content.
3138 MockRead("HTTP/1.1 200 OK\r\n"),
3139 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503140 MockRead("Content-Length: 5\r\n\r\n"),
3141 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323142 };
3143
[email protected]2d0a4f92011-05-05 16:38:463144 // An incorrect reconnect would cause this to be read.
3145 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063146 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463147 };
3148
Ryan Sleevib8d7ea02018-05-07 20:01:013149 StaticSocketDataProvider data1(data_reads1, data_writes1);
3150 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073151 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3152 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323153
[email protected]49639fa2011-12-20 23:22:413154 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323155
bnc691fda62016-08-12 00:43:163156 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203157 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323159
3160 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013161 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323162
bnc691fda62016-08-12 00:43:163163 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523164 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583165 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]2d2697f92009-02-18 21:00:323166
[email protected]49639fa2011-12-20 23:22:413167 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323168
bnc691fda62016-08-12 00:43:163169 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013170 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323171
3172 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013173 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323174
bnc691fda62016-08-12 00:43:163175 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523176 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583177 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0b0bf032010-09-21 18:08:503178 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323179}
3180
3181// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:313182// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:013183TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:313184 HttpRequestInfo request;
3185 request.method = "GET";
bncce36dca22015-04-21 22:11:233186 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103187 request.traffic_annotation =
3188 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313189
danakj1fd259a02016-04-16 03:17:093190 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273191
[email protected]11203f012009-11-12 23:02:313192 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233193 MockWrite(
3194 "GET / HTTP/1.1\r\n"
3195 "Host: www.example.org\r\n"
3196 "Connection: keep-alive\r\n\r\n"),
3197 // This simulates the seemingly successful write to a closed connection
3198 // if the bug is not fixed.
3199 MockWrite(
3200 "GET / HTTP/1.1\r\n"
3201 "Host: www.example.org\r\n"
3202 "Connection: keep-alive\r\n"
3203 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313204 };
3205
3206 MockRead data_reads1[] = {
3207 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3208 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3209 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3210 MockRead("Content-Length: 14\r\n\r\n"),
3211 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063212 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313213 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063214 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313215 };
3216
bnc691fda62016-08-12 00:43:163217 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313218 // be issuing -- the final header line contains the credentials.
3219 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233220 MockWrite(
3221 "GET / HTTP/1.1\r\n"
3222 "Host: www.example.org\r\n"
3223 "Connection: keep-alive\r\n"
3224 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313225 };
3226
3227 // Lastly, the server responds with the actual content.
3228 MockRead data_reads2[] = {
3229 MockRead("HTTP/1.1 200 OK\r\n"),
3230 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503231 MockRead("Content-Length: 5\r\n\r\n"),
3232 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313233 };
3234
Ryan Sleevib8d7ea02018-05-07 20:01:013235 StaticSocketDataProvider data1(data_reads1, data_writes1);
3236 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:073237 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3238 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313239
[email protected]49639fa2011-12-20 23:22:413240 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313241
bnc691fda62016-08-12 00:43:163242 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203243 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013244 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313245
3246 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013247 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313248
bnc691fda62016-08-12 00:43:163249 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523250 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583251 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]11203f012009-11-12 23:02:313252
[email protected]49639fa2011-12-20 23:22:413253 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313254
bnc691fda62016-08-12 00:43:163255 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013256 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313257
3258 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013259 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313260
bnc691fda62016-08-12 00:43:163261 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523262 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583263 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0b0bf032010-09-21 18:08:503264 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313265}
3266
[email protected]394816e92010-08-03 07:38:593267// Test the request-challenge-retry sequence for basic auth, over a connection
3268// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013269TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013270 HttpRequestInfo request;
3271 request.method = "GET";
bncce36dca22015-04-21 22:11:233272 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013273 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293274 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103275 request.traffic_annotation =
3276 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013277
3278 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593279 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493280 ProxyResolutionService::CreateFixedFromPacResult(
3281 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513282 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013283 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093284 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013285
3286 // Since we have proxy, should try to establish tunnel.
3287 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543288 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173289 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543290 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013291 };
3292
mmenkee71e15332015-10-07 16:39:543293 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013294 // connection.
3295 MockRead data_reads1[] = {
3296 // No credentials.
3297 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3298 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543299 };
ttuttle34f63b52015-03-05 04:33:013300
mmenkee71e15332015-10-07 16:39:543301 // Since the first connection couldn't be reused, need to establish another
3302 // once given credentials.
3303 MockWrite data_writes2[] = {
3304 // After calling trans->RestartWithAuth(), this is the request we should
3305 // be issuing -- the final header line contains the credentials.
3306 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173307 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543308 "Proxy-Connection: keep-alive\r\n"
3309 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3310
3311 MockWrite("GET / HTTP/1.1\r\n"
3312 "Host: www.example.org\r\n"
3313 "Connection: keep-alive\r\n\r\n"),
3314 };
3315
3316 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013317 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3318
3319 MockRead("HTTP/1.1 200 OK\r\n"),
3320 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3321 MockRead("Content-Length: 5\r\n\r\n"),
3322 MockRead(SYNCHRONOUS, "hello"),
3323 };
3324
Ryan Sleevib8d7ea02018-05-07 20:01:013325 StaticSocketDataProvider data1(data_reads1, data_writes1);
ttuttle34f63b52015-03-05 04:33:013326 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013327 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543328 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013329 SSLSocketDataProvider ssl(ASYNC, OK);
3330 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3331
3332 TestCompletionCallback callback1;
3333
bnc87dcefc2017-05-25 12:47:583334 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193335 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013336
3337 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013338 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013339
3340 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013341 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463342 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013343 log.GetEntries(&entries);
3344 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003345 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3346 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013347 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003348 entries, pos,
3349 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3350 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013351
3352 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523353 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013354 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523355 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013356 EXPECT_EQ(407, response->headers->response_code());
3357 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583358 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
ttuttle34f63b52015-03-05 04:33:013359
3360 LoadTimingInfo load_timing_info;
3361 // CONNECT requests and responses are handled at the connect job level, so
3362 // the transaction does not yet have a connection.
3363 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3364
3365 TestCompletionCallback callback2;
3366
3367 rv =
3368 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013369 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013370
3371 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013372 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013373
3374 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523375 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013376
3377 EXPECT_TRUE(response->headers->IsKeepAlive());
3378 EXPECT_EQ(200, response->headers->response_code());
3379 EXPECT_EQ(5, response->headers->GetContentLength());
3380 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3381
3382 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:583383 EXPECT_FALSE(response->auth_challenge.has_value());
ttuttle34f63b52015-03-05 04:33:013384
3385 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3386 TestLoadTimingNotReusedWithPac(load_timing_info,
3387 CONNECT_TIMING_HAS_SSL_TIMES);
3388
3389 trans.reset();
3390 session->CloseAllConnections();
3391}
3392
3393// Test the request-challenge-retry sequence for basic auth, over a connection
3394// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013395TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593396 HttpRequestInfo request;
3397 request.method = "GET";
bncce36dca22015-04-21 22:11:233398 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593399 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293400 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103401 request.traffic_annotation =
3402 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593403
[email protected]cb9bf6ca2011-01-28 13:15:273404 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593405 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493406 ProxyResolutionService::CreateFixedFromPacResult(
3407 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513408 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073409 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093410 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273411
[email protected]394816e92010-08-03 07:38:593412 // Since we have proxy, should try to establish tunnel.
3413 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543414 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173415 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543416 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113417 };
3418
mmenkee71e15332015-10-07 16:39:543419 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083420 // connection.
3421 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543422 // No credentials.
3423 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3424 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3425 MockRead("Proxy-Connection: close\r\n\r\n"),
3426 };
mmenkee0b5c882015-08-26 20:29:113427
mmenkee71e15332015-10-07 16:39:543428 MockWrite data_writes2[] = {
3429 // After calling trans->RestartWithAuth(), this is the request we should
3430 // be issuing -- the final header line contains the credentials.
3431 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173432 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543433 "Proxy-Connection: keep-alive\r\n"
3434 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083435
mmenkee71e15332015-10-07 16:39:543436 MockWrite("GET / HTTP/1.1\r\n"
3437 "Host: www.example.org\r\n"
3438 "Connection: keep-alive\r\n\r\n"),
3439 };
3440
3441 MockRead data_reads2[] = {
3442 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3443
3444 MockRead("HTTP/1.1 200 OK\r\n"),
3445 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3446 MockRead("Content-Length: 5\r\n\r\n"),
3447 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593448 };
3449
Ryan Sleevib8d7ea02018-05-07 20:01:013450 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073451 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013452 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543453 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063454 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073455 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593456
[email protected]49639fa2011-12-20 23:22:413457 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593458
bnc87dcefc2017-05-25 12:47:583459 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193460 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503461
[email protected]49639fa2011-12-20 23:22:413462 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013463 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593464
3465 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013466 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463467 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403468 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593469 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003470 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3471 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593472 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403473 entries, pos,
mikecirone8b85c432016-09-08 19:11:003474 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3475 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593476
3477 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523478 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013479 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523480 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593481 EXPECT_EQ(407, response->headers->response_code());
3482 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583483 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
[email protected]394816e92010-08-03 07:38:593484
[email protected]029c83b62013-01-24 05:28:203485 LoadTimingInfo load_timing_info;
3486 // CONNECT requests and responses are handled at the connect job level, so
3487 // the transaction does not yet have a connection.
3488 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3489
[email protected]49639fa2011-12-20 23:22:413490 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593491
[email protected]49639fa2011-12-20 23:22:413492 rv = trans->RestartWithAuth(
3493 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013494 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593495
3496 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013497 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593498
3499 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523500 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593501
3502 EXPECT_TRUE(response->headers->IsKeepAlive());
3503 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503504 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593505 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3506
3507 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:583508 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0b0bf032010-09-21 18:08:503509
[email protected]029c83b62013-01-24 05:28:203510 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3511 TestLoadTimingNotReusedWithPac(load_timing_info,
3512 CONNECT_TIMING_HAS_SSL_TIMES);
3513
[email protected]0b0bf032010-09-21 18:08:503514 trans.reset();
[email protected]102e27c2011-02-23 01:01:313515 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593516}
3517
[email protected]11203f012009-11-12 23:02:313518// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013519// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013520TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233521 // On the second pass, the body read of the auth challenge is synchronous, so
3522 // IsConnectedAndIdle returns false. The socket should still be drained and
3523 // reused. See http://crbug.com/544255.
3524 for (int i = 0; i < 2; ++i) {
3525 HttpRequestInfo request;
3526 request.method = "GET";
3527 request.url = GURL("https://www.example.org/");
3528 // Ensure that proxy authentication is attempted even
3529 // when the no authentication data flag is set.
3530 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103531 request.traffic_annotation =
3532 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013533
mmenked39192ee2015-12-09 00:57:233534 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593535 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493536 ProxyResolutionService::CreateFixed("myproxy:70",
3537 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233538 BoundTestNetLog log;
3539 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093540 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013541
bnc691fda62016-08-12 00:43:163542 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013543
mmenked39192ee2015-12-09 00:57:233544 // Since we have proxy, should try to establish tunnel.
3545 MockWrite data_writes1[] = {
3546 MockWrite(ASYNC, 0,
3547 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3548 "Host: www.example.org:443\r\n"
3549 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013550
bnc691fda62016-08-12 00:43:163551 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233552 // be issuing -- the final header line contains the credentials.
3553 MockWrite(ASYNC, 3,
3554 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3555 "Host: www.example.org:443\r\n"
3556 "Proxy-Connection: keep-alive\r\n"
3557 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3558 };
ttuttle34f63b52015-03-05 04:33:013559
mmenked39192ee2015-12-09 00:57:233560 // The proxy responds to the connect with a 407, using a persistent
3561 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3562 MockRead data_reads1[] = {
3563 // No credentials.
3564 MockRead(ASYNC, 1,
3565 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3566 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3567 "Proxy-Connection: keep-alive\r\n"
3568 "Content-Length: 10\r\n\r\n"),
3569 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013570
mmenked39192ee2015-12-09 00:57:233571 // Wrong credentials (wrong password).
3572 MockRead(ASYNC, 4,
3573 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3574 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3575 "Proxy-Connection: keep-alive\r\n"
3576 "Content-Length: 10\r\n\r\n"),
3577 // No response body because the test stops reading here.
3578 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3579 };
ttuttle34f63b52015-03-05 04:33:013580
Ryan Sleevib8d7ea02018-05-07 20:01:013581 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233582 data1.set_busy_before_sync_reads(true);
3583 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013584
mmenked39192ee2015-12-09 00:57:233585 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013586
bnc691fda62016-08-12 00:43:163587 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013588 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013589
mmenked39192ee2015-12-09 00:57:233590 TestNetLogEntry::List entries;
3591 log.GetEntries(&entries);
3592 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003593 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3594 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233595 ExpectLogContainsSomewhere(
3596 entries, pos,
mikecirone8b85c432016-09-08 19:11:003597 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3598 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013599
bnc691fda62016-08-12 00:43:163600 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233601 ASSERT_TRUE(response);
3602 ASSERT_TRUE(response->headers);
3603 EXPECT_TRUE(response->headers->IsKeepAlive());
3604 EXPECT_EQ(407, response->headers->response_code());
3605 EXPECT_EQ(10, response->headers->GetContentLength());
3606 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583607 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
ttuttle34f63b52015-03-05 04:33:013608
mmenked39192ee2015-12-09 00:57:233609 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013610
mmenked39192ee2015-12-09 00:57:233611 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163612 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3613 callback2.callback());
robpercival214763f2016-07-01 23:27:013614 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013615
bnc691fda62016-08-12 00:43:163616 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233617 ASSERT_TRUE(response);
3618 ASSERT_TRUE(response->headers);
3619 EXPECT_TRUE(response->headers->IsKeepAlive());
3620 EXPECT_EQ(407, response->headers->response_code());
3621 EXPECT_EQ(10, response->headers->GetContentLength());
3622 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583623 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
ttuttle34f63b52015-03-05 04:33:013624
mmenked39192ee2015-12-09 00:57:233625 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3626 // out of scope.
3627 session->CloseAllConnections();
3628 }
ttuttle34f63b52015-03-05 04:33:013629}
3630
3631// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3632// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013633TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233634 // On the second pass, the body read of the auth challenge is synchronous, so
3635 // IsConnectedAndIdle returns false. The socket should still be drained and
3636 // reused. See http://crbug.com/544255.
3637 for (int i = 0; i < 2; ++i) {
3638 HttpRequestInfo request;
3639 request.method = "GET";
3640 request.url = GURL("https://www.example.org/");
3641 // Ensure that proxy authentication is attempted even
3642 // when the no authentication data flag is set.
3643 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103644 request.traffic_annotation =
3645 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233646
3647 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593648 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493649 ProxyResolutionService::CreateFixed("myproxy:70",
3650 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233651 BoundTestNetLog log;
3652 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093653 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233654
bnc691fda62016-08-12 00:43:163655 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233656
3657 // Since we have proxy, should try to establish tunnel.
3658 MockWrite data_writes1[] = {
3659 MockWrite(ASYNC, 0,
3660 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3661 "Host: www.example.org:443\r\n"
3662 "Proxy-Connection: keep-alive\r\n\r\n"),
3663
bnc691fda62016-08-12 00:43:163664 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233665 // be issuing -- the final header line contains the credentials.
3666 MockWrite(ASYNC, 3,
3667 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3668 "Host: www.example.org:443\r\n"
3669 "Proxy-Connection: keep-alive\r\n"
3670 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3671 };
3672
3673 // The proxy responds to the connect with a 407, using a persistent
3674 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3675 MockRead data_reads1[] = {
3676 // No credentials.
3677 MockRead(ASYNC, 1,
3678 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3679 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3680 "Content-Length: 10\r\n\r\n"),
3681 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3682
3683 // Wrong credentials (wrong password).
3684 MockRead(ASYNC, 4,
3685 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3686 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3687 "Content-Length: 10\r\n\r\n"),
3688 // No response body because the test stops reading here.
3689 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3690 };
3691
Ryan Sleevib8d7ea02018-05-07 20:01:013692 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233693 data1.set_busy_before_sync_reads(true);
3694 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3695
3696 TestCompletionCallback callback1;
3697
bnc691fda62016-08-12 00:43:163698 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013699 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233700
3701 TestNetLogEntry::List entries;
3702 log.GetEntries(&entries);
3703 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003704 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3705 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233706 ExpectLogContainsSomewhere(
3707 entries, pos,
mikecirone8b85c432016-09-08 19:11:003708 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3709 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233710
bnc691fda62016-08-12 00:43:163711 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233712 ASSERT_TRUE(response);
3713 ASSERT_TRUE(response->headers);
3714 EXPECT_TRUE(response->headers->IsKeepAlive());
3715 EXPECT_EQ(407, response->headers->response_code());
3716 EXPECT_EQ(10, response->headers->GetContentLength());
3717 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583718 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
Wojciech Dzierżanowski0950c372019-04-02 19:29:503719 EXPECT_FALSE(response->did_use_http_auth);
mmenked39192ee2015-12-09 00:57:233720
3721 TestCompletionCallback callback2;
3722
3723 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163724 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3725 callback2.callback());
robpercival214763f2016-07-01 23:27:013726 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233727
bnc691fda62016-08-12 00:43:163728 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233729 ASSERT_TRUE(response);
3730 ASSERT_TRUE(response->headers);
3731 EXPECT_TRUE(response->headers->IsKeepAlive());
3732 EXPECT_EQ(407, response->headers->response_code());
3733 EXPECT_EQ(10, response->headers->GetContentLength());
3734 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583735 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
Wojciech Dzierżanowski0950c372019-04-02 19:29:503736 EXPECT_TRUE(response->did_use_http_auth);
mmenked39192ee2015-12-09 00:57:233737
3738 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3739 // out of scope.
3740 session->CloseAllConnections();
3741 }
3742}
3743
3744// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3745// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3746// the case the server sends extra data on the original socket, so it can't be
3747// reused.
bncd16676a2016-07-20 16:23:013748TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273749 HttpRequestInfo request;
3750 request.method = "GET";
bncce36dca22015-04-21 22:11:233751 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273752 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293753 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103754 request.traffic_annotation =
3755 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273756
[email protected]2d2697f92009-02-18 21:00:323757 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593758 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493759 ProxyResolutionService::CreateFixedFromPacResult(
3760 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513761 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073762 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093763 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323764
[email protected]2d2697f92009-02-18 21:00:323765 // Since we have proxy, should try to establish tunnel.
3766 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233767 MockWrite(ASYNC, 0,
3768 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173769 "Host: www.example.org:443\r\n"
3770 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233771 };
[email protected]2d2697f92009-02-18 21:00:323772
mmenked39192ee2015-12-09 00:57:233773 // The proxy responds to the connect with a 407, using a persistent, but sends
3774 // extra data, so the socket cannot be reused.
3775 MockRead data_reads1[] = {
3776 // No credentials.
3777 MockRead(ASYNC, 1,
3778 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3779 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3780 "Content-Length: 10\r\n\r\n"),
3781 MockRead(SYNCHRONOUS, 2, "0123456789"),
3782 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3783 };
3784
3785 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233786 // After calling trans->RestartWithAuth(), this is the request we should
3787 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233788 MockWrite(ASYNC, 0,
3789 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173790 "Host: www.example.org:443\r\n"
3791 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233792 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3793
3794 MockWrite(ASYNC, 2,
3795 "GET / HTTP/1.1\r\n"
3796 "Host: www.example.org\r\n"
3797 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323798 };
3799
mmenked39192ee2015-12-09 00:57:233800 MockRead data_reads2[] = {
3801 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323802
mmenked39192ee2015-12-09 00:57:233803 MockRead(ASYNC, 3,
3804 "HTTP/1.1 200 OK\r\n"
3805 "Content-Type: text/html; charset=iso-8859-1\r\n"
3806 "Content-Length: 5\r\n\r\n"),
3807 // No response body because the test stops reading here.
3808 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323809 };
3810
Ryan Sleevib8d7ea02018-05-07 20:01:013811 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233812 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073813 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013814 SequencedSocketData data2(data_reads2, data_writes2);
mmenked39192ee2015-12-09 00:57:233815 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3816 SSLSocketDataProvider ssl(ASYNC, OK);
3817 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323818
[email protected]49639fa2011-12-20 23:22:413819 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323820
bnc87dcefc2017-05-25 12:47:583821 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193822 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323823
mmenked39192ee2015-12-09 00:57:233824 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013825 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233826
mmenke43758e62015-05-04 21:09:463827 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403828 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393829 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003830 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3831 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393832 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403833 entries, pos,
mikecirone8b85c432016-09-08 19:11:003834 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3835 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323836
[email protected]1c773ea12009-04-28 19:58:423837 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243838 ASSERT_TRUE(response);
3839 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323840 EXPECT_TRUE(response->headers->IsKeepAlive());
3841 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423842 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583843 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
[email protected]2d2697f92009-02-18 21:00:323844
mmenked39192ee2015-12-09 00:57:233845 LoadTimingInfo load_timing_info;
3846 // CONNECT requests and responses are handled at the connect job level, so
3847 // the transaction does not yet have a connection.
3848 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3849
[email protected]49639fa2011-12-20 23:22:413850 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323851
mmenked39192ee2015-12-09 00:57:233852 rv =
3853 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013854 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323855
[email protected]2d2697f92009-02-18 21:00:323856 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233857 EXPECT_EQ(200, response->headers->response_code());
3858 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423859 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133860
mmenked39192ee2015-12-09 00:57:233861 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:583862 EXPECT_FALSE(response->auth_challenge.has_value());
mmenked39192ee2015-12-09 00:57:233863
3864 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3865 TestLoadTimingNotReusedWithPac(load_timing_info,
3866 CONNECT_TIMING_HAS_SSL_TIMES);
3867
3868 trans.reset();
[email protected]102e27c2011-02-23 01:01:313869 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323870}
3871
mmenkee71e15332015-10-07 16:39:543872// Test the case a proxy closes a socket while the challenge body is being
3873// drained.
bncd16676a2016-07-20 16:23:013874TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543875 HttpRequestInfo request;
3876 request.method = "GET";
3877 request.url = GURL("https://www.example.org/");
3878 // Ensure that proxy authentication is attempted even
3879 // when the no authentication data flag is set.
3880 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103881 request.traffic_annotation =
3882 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543883
3884 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493885 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3886 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093887 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543888
bnc691fda62016-08-12 00:43:163889 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543890
3891 // Since we have proxy, should try to establish tunnel.
3892 MockWrite data_writes1[] = {
3893 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173894 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543895 "Proxy-Connection: keep-alive\r\n\r\n"),
3896 };
3897
3898 // The proxy responds to the connect with a 407, using a persistent
3899 // connection.
3900 MockRead data_reads1[] = {
3901 // No credentials.
3902 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3903 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3904 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3905 // Server hands up in the middle of the body.
3906 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3907 };
3908
3909 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163910 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543911 // be issuing -- the final header line contains the credentials.
3912 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173913 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543914 "Proxy-Connection: keep-alive\r\n"
3915 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3916
3917 MockWrite("GET / HTTP/1.1\r\n"
3918 "Host: www.example.org\r\n"
3919 "Connection: keep-alive\r\n\r\n"),
3920 };
3921
3922 MockRead data_reads2[] = {
3923 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3924
3925 MockRead("HTTP/1.1 200 OK\r\n"),
3926 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3927 MockRead("Content-Length: 5\r\n\r\n"),
3928 MockRead(SYNCHRONOUS, "hello"),
3929 };
3930
Ryan Sleevib8d7ea02018-05-07 20:01:013931 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenkee71e15332015-10-07 16:39:543932 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013933 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543934 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3935 SSLSocketDataProvider ssl(ASYNC, OK);
3936 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3937
3938 TestCompletionCallback callback;
3939
tfarina42834112016-09-22 13:38:203940 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013941 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543942
bnc691fda62016-08-12 00:43:163943 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543944 ASSERT_TRUE(response);
3945 ASSERT_TRUE(response->headers);
3946 EXPECT_TRUE(response->headers->IsKeepAlive());
3947 EXPECT_EQ(407, response->headers->response_code());
Emily Starkf2c9bbd2019-04-09 17:08:583948 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
mmenkee71e15332015-10-07 16:39:543949
bnc691fda62016-08-12 00:43:163950 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013951 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543952
bnc691fda62016-08-12 00:43:163953 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543954 ASSERT_TRUE(response);
3955 ASSERT_TRUE(response->headers);
3956 EXPECT_TRUE(response->headers->IsKeepAlive());
3957 EXPECT_EQ(200, response->headers->response_code());
3958 std::string body;
bnc691fda62016-08-12 00:43:163959 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543960 EXPECT_EQ("hello", body);
3961}
3962
[email protected]a8e9b162009-03-12 00:06:443963// Test that we don't read the response body when we fail to establish a tunnel,
3964// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013965TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273966 HttpRequestInfo request;
3967 request.method = "GET";
bncce36dca22015-04-21 22:11:233968 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103969 request.traffic_annotation =
3970 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273971
[email protected]a8e9b162009-03-12 00:06:443972 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493973 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3974 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443975
danakj1fd259a02016-04-16 03:17:093976 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443977
bnc691fda62016-08-12 00:43:163978 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443979
[email protected]a8e9b162009-03-12 00:06:443980 // Since we have proxy, should try to establish tunnel.
3981 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173982 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3983 "Host: www.example.org:443\r\n"
3984 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443985 };
3986
3987 // The proxy responds to the connect with a 407.
3988 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243989 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3990 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3991 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233992 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243993 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443994 };
3995
Ryan Sleevib8d7ea02018-05-07 20:01:013996 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:073997 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443998
[email protected]49639fa2011-12-20 23:22:413999 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:444000
tfarina42834112016-09-22 13:38:204001 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014002 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:444003
4004 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014005 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:444006
bnc691fda62016-08-12 00:43:164007 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244008 ASSERT_TRUE(response);
4009 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:444010 EXPECT_TRUE(response->headers->IsKeepAlive());
4011 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:424012 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:444013
4014 std::string response_data;
bnc691fda62016-08-12 00:43:164015 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014016 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:184017
4018 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:314019 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:444020}
4021
ttuttle7933c112015-01-06 00:55:244022// Test that we don't pass extraneous headers from the proxy's response to the
4023// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:014024TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:244025 HttpRequestInfo request;
4026 request.method = "GET";
bncce36dca22015-04-21 22:11:234027 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104028 request.traffic_annotation =
4029 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244030
4031 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494032 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4033 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244034
danakj1fd259a02016-04-16 03:17:094035 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:244036
bnc691fda62016-08-12 00:43:164037 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:244038
4039 // Since we have proxy, should try to establish tunnel.
4040 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:174041 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4042 "Host: www.example.org:443\r\n"
4043 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:244044 };
4045
4046 // The proxy responds to the connect with a 407.
4047 MockRead data_reads[] = {
4048 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4049 MockRead("X-Foo: bar\r\n"),
4050 MockRead("Set-Cookie: foo=bar\r\n"),
4051 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4052 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:234053 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:244054 };
4055
Ryan Sleevib8d7ea02018-05-07 20:01:014056 StaticSocketDataProvider data(data_reads, data_writes);
ttuttle7933c112015-01-06 00:55:244057 session_deps_.socket_factory->AddSocketDataProvider(&data);
4058
4059 TestCompletionCallback callback;
4060
tfarina42834112016-09-22 13:38:204061 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014062 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:244063
4064 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014065 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:244066
bnc691fda62016-08-12 00:43:164067 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244068 ASSERT_TRUE(response);
4069 ASSERT_TRUE(response->headers);
4070 EXPECT_TRUE(response->headers->IsKeepAlive());
4071 EXPECT_EQ(407, response->headers->response_code());
4072 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4073 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
4074 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
4075
4076 std::string response_data;
bnc691fda62016-08-12 00:43:164077 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014078 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:244079
4080 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
4081 session->CloseAllConnections();
4082}
4083
[email protected]8fdbcd22010-05-05 02:54:524084// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
4085// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:014086TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:524087 HttpRequestInfo request;
4088 request.method = "GET";
bncce36dca22015-04-21 22:11:234089 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104090 request.traffic_annotation =
4091 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:524092
[email protected]cb9bf6ca2011-01-28 13:15:274093 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:094094 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:164095 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:274096
[email protected]8fdbcd22010-05-05 02:54:524097 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234098 MockWrite(
4099 "GET / HTTP/1.1\r\n"
4100 "Host: www.example.org\r\n"
4101 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:524102 };
4103
4104 MockRead data_reads1[] = {
4105 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
4106 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4107 // Large content-length -- won't matter, as connection will be reset.
4108 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064109 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:524110 };
4111
Ryan Sleevib8d7ea02018-05-07 20:01:014112 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074113 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:524114
[email protected]49639fa2011-12-20 23:22:414115 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:524116
tfarina42834112016-09-22 13:38:204117 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:524119
4120 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014121 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:524122}
4123
[email protected]7a67a8152010-11-05 18:31:104124// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
4125// through a non-authenticating proxy. The request should fail with
4126// ERR_UNEXPECTED_PROXY_AUTH.
4127// Note that it is impossible to detect if an HTTP server returns a 407 through
4128// a non-authenticating proxy - there is nothing to indicate whether the
4129// response came from the proxy or the server, so it is treated as if the proxy
4130// issued the challenge.
bncd16676a2016-07-20 16:23:014131TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:274132 HttpRequestInfo request;
4133 request.method = "GET";
bncce36dca22015-04-21 22:11:234134 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104135 request.traffic_annotation =
4136 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274137
Ramin Halavatica8d5252018-03-12 05:33:494138 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4139 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514140 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074141 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094142 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:104143
[email protected]7a67a8152010-11-05 18:31:104144 // Since we have proxy, should try to establish tunnel.
4145 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174146 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4147 "Host: www.example.org:443\r\n"
4148 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104149
rsleevidb16bb02015-11-12 23:47:174150 MockWrite("GET / HTTP/1.1\r\n"
4151 "Host: www.example.org\r\n"
4152 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104153 };
4154
4155 MockRead data_reads1[] = {
4156 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4157
4158 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
4159 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4160 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:064161 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:104162 };
4163
Ryan Sleevib8d7ea02018-05-07 20:01:014164 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074165 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064166 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074167 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:104168
[email protected]49639fa2011-12-20 23:22:414169 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:104170
bnc691fda62016-08-12 00:43:164171 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:104172
bnc691fda62016-08-12 00:43:164173 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014174 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:104175
4176 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014177 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464178 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404179 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104180 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004181 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4182 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104183 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404184 entries, pos,
mikecirone8b85c432016-09-08 19:11:004185 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4186 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104187}
[email protected]2df19bb2010-08-25 20:13:464188
mmenke2a1781d2015-10-07 19:25:334189// Test a proxy auth scheme that allows default credentials and a proxy server
4190// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014191TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334192 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4193 HttpRequestInfo request;
4194 request.method = "GET";
4195 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104196 request.traffic_annotation =
4197 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334198
4199 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594200 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494201 ProxyResolutionService::CreateFixedFromPacResult(
4202 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334203
Jeremy Roman0579ed62017-08-29 15:56:194204 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334205 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194206 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334207 mock_handler->set_allows_default_credentials(true);
4208 auth_handler_factory->AddMockHandler(mock_handler.release(),
4209 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484210 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334211
4212 // Add NetLog just so can verify load timing information gets a NetLog ID.
4213 NetLog net_log;
4214 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094215 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334216
4217 // Since we have proxy, should try to establish tunnel.
4218 MockWrite data_writes1[] = {
4219 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174220 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334221 "Proxy-Connection: keep-alive\r\n\r\n"),
4222 };
4223
4224 // The proxy responds to the connect with a 407, using a non-persistent
4225 // connection.
4226 MockRead data_reads1[] = {
4227 // No credentials.
4228 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4229 MockRead("Proxy-Authenticate: Mock\r\n"),
4230 MockRead("Proxy-Connection: close\r\n\r\n"),
4231 };
4232
4233 // Since the first connection couldn't be reused, need to establish another
4234 // once given credentials.
4235 MockWrite data_writes2[] = {
4236 // After calling trans->RestartWithAuth(), this is the request we should
4237 // be issuing -- the final header line contains the credentials.
4238 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174239 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334240 "Proxy-Connection: keep-alive\r\n"
4241 "Proxy-Authorization: auth_token\r\n\r\n"),
4242
4243 MockWrite("GET / HTTP/1.1\r\n"
4244 "Host: www.example.org\r\n"
4245 "Connection: keep-alive\r\n\r\n"),
4246 };
4247
4248 MockRead data_reads2[] = {
4249 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4250
4251 MockRead("HTTP/1.1 200 OK\r\n"),
4252 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4253 MockRead("Content-Length: 5\r\n\r\n"),
4254 MockRead(SYNCHRONOUS, "hello"),
4255 };
4256
Ryan Sleevib8d7ea02018-05-07 20:01:014257 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334258 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014259 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334260 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4261 SSLSocketDataProvider ssl(ASYNC, OK);
4262 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4263
bnc87dcefc2017-05-25 12:47:584264 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194265 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334266
4267 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204268 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014269 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334270
4271 const HttpResponseInfo* response = trans->GetResponseInfo();
4272 ASSERT_TRUE(response);
4273 ASSERT_TRUE(response->headers);
4274 EXPECT_FALSE(response->headers->IsKeepAlive());
4275 EXPECT_EQ(407, response->headers->response_code());
4276 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4277 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584278 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334279
4280 LoadTimingInfo load_timing_info;
4281 // CONNECT requests and responses are handled at the connect job level, so
4282 // the transaction does not yet have a connection.
4283 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4284
4285 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014286 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334287 response = trans->GetResponseInfo();
4288 ASSERT_TRUE(response);
4289 ASSERT_TRUE(response->headers);
4290 EXPECT_TRUE(response->headers->IsKeepAlive());
4291 EXPECT_EQ(200, response->headers->response_code());
4292 EXPECT_EQ(5, response->headers->GetContentLength());
4293 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4294
4295 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:584296 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334297
4298 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4299 TestLoadTimingNotReusedWithPac(load_timing_info,
4300 CONNECT_TIMING_HAS_SSL_TIMES);
4301
4302 trans.reset();
4303 session->CloseAllConnections();
4304}
4305
4306// Test a proxy auth scheme that allows default credentials and a proxy server
4307// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014308TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334309 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4310 HttpRequestInfo request;
4311 request.method = "GET";
4312 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104313 request.traffic_annotation =
4314 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334315
4316 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594317 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494318 ProxyResolutionService::CreateFixedFromPacResult(
4319 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334320
Jeremy Roman0579ed62017-08-29 15:56:194321 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334322 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194323 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334324 mock_handler->set_allows_default_credentials(true);
4325 auth_handler_factory->AddMockHandler(mock_handler.release(),
4326 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484327 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334328
4329 // Add NetLog just so can verify load timing information gets a NetLog ID.
4330 NetLog net_log;
4331 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094332 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334333
4334 // Should try to establish tunnel.
4335 MockWrite data_writes1[] = {
4336 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174337 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334338 "Proxy-Connection: keep-alive\r\n\r\n"),
4339
4340 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174341 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334342 "Proxy-Connection: keep-alive\r\n"
4343 "Proxy-Authorization: auth_token\r\n\r\n"),
4344 };
4345
4346 // The proxy responds to the connect with a 407, using a non-persistent
4347 // connection.
4348 MockRead data_reads1[] = {
4349 // No credentials.
4350 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4351 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4352 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4353 };
4354
4355 // Since the first connection was closed, need to establish another once given
4356 // credentials.
4357 MockWrite data_writes2[] = {
4358 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174359 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334360 "Proxy-Connection: keep-alive\r\n"
4361 "Proxy-Authorization: auth_token\r\n\r\n"),
4362
4363 MockWrite("GET / HTTP/1.1\r\n"
4364 "Host: www.example.org\r\n"
4365 "Connection: keep-alive\r\n\r\n"),
4366 };
4367
4368 MockRead data_reads2[] = {
4369 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4370
4371 MockRead("HTTP/1.1 200 OK\r\n"),
4372 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4373 MockRead("Content-Length: 5\r\n\r\n"),
4374 MockRead(SYNCHRONOUS, "hello"),
4375 };
4376
Ryan Sleevib8d7ea02018-05-07 20:01:014377 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334378 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014379 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334380 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4381 SSLSocketDataProvider ssl(ASYNC, OK);
4382 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4383
bnc87dcefc2017-05-25 12:47:584384 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194385 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334386
4387 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204388 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014389 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334390
4391 const HttpResponseInfo* response = trans->GetResponseInfo();
4392 ASSERT_TRUE(response);
4393 ASSERT_TRUE(response->headers);
4394 EXPECT_TRUE(response->headers->IsKeepAlive());
4395 EXPECT_EQ(407, response->headers->response_code());
4396 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4397 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584398 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334399
4400 LoadTimingInfo load_timing_info;
4401 // CONNECT requests and responses are handled at the connect job level, so
4402 // the transaction does not yet have a connection.
4403 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4404
4405 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014406 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334407
4408 response = trans->GetResponseInfo();
4409 ASSERT_TRUE(response);
4410 ASSERT_TRUE(response->headers);
4411 EXPECT_TRUE(response->headers->IsKeepAlive());
4412 EXPECT_EQ(200, response->headers->response_code());
4413 EXPECT_EQ(5, response->headers->GetContentLength());
4414 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4415
4416 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:584417 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334418
4419 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4420 TestLoadTimingNotReusedWithPac(load_timing_info,
4421 CONNECT_TIMING_HAS_SSL_TIMES);
4422
4423 trans.reset();
4424 session->CloseAllConnections();
4425}
4426
4427// Test a proxy auth scheme that allows default credentials and a proxy server
4428// that hangs up when credentials are initially sent, and hangs up again when
4429// they are retried.
bncd16676a2016-07-20 16:23:014430TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334431 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4432 HttpRequestInfo request;
4433 request.method = "GET";
4434 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104435 request.traffic_annotation =
4436 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334437
4438 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594439 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494440 ProxyResolutionService::CreateFixedFromPacResult(
4441 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334442
Jeremy Roman0579ed62017-08-29 15:56:194443 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334444 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194445 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334446 mock_handler->set_allows_default_credentials(true);
4447 auth_handler_factory->AddMockHandler(mock_handler.release(),
4448 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484449 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334450
4451 // Add NetLog just so can verify load timing information gets a NetLog ID.
4452 NetLog net_log;
4453 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094454 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334455
4456 // Should try to establish tunnel.
4457 MockWrite data_writes1[] = {
4458 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174459 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334460 "Proxy-Connection: keep-alive\r\n\r\n"),
4461
4462 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174463 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334464 "Proxy-Connection: keep-alive\r\n"
4465 "Proxy-Authorization: auth_token\r\n\r\n"),
4466 };
4467
4468 // The proxy responds to the connect with a 407, and then hangs up after the
4469 // second request is sent.
4470 MockRead data_reads1[] = {
4471 // No credentials.
4472 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4473 MockRead("Content-Length: 0\r\n"),
4474 MockRead("Proxy-Connection: keep-alive\r\n"),
4475 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4476 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4477 };
4478
4479 // HttpNetworkTransaction sees a reused connection that was closed with
4480 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4481 // request.
4482 MockWrite data_writes2[] = {
4483 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174484 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334485 "Proxy-Connection: keep-alive\r\n\r\n"),
4486 };
4487
4488 // The proxy, having had more than enough of us, just hangs up.
4489 MockRead data_reads2[] = {
4490 // No credentials.
4491 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4492 };
4493
Ryan Sleevib8d7ea02018-05-07 20:01:014494 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334495 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014496 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334497 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4498
bnc87dcefc2017-05-25 12:47:584499 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194500 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334501
4502 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204503 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014504 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334505
4506 const HttpResponseInfo* response = trans->GetResponseInfo();
4507 ASSERT_TRUE(response);
4508 ASSERT_TRUE(response->headers);
4509 EXPECT_TRUE(response->headers->IsKeepAlive());
4510 EXPECT_EQ(407, response->headers->response_code());
4511 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4512 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584513 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334514
4515 LoadTimingInfo load_timing_info;
4516 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4517
4518 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014519 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334520
4521 trans.reset();
4522 session->CloseAllConnections();
4523}
4524
Asanka Herathbc3f8f62018-11-16 23:08:304525// This test exercises an odd edge case where the proxy closes the connection
4526// after the authentication handshake is complete. Presumably this technique is
4527// used in lieu of returning a 403 or 5xx status code when the authentication
4528// succeeds, but the user is not authorized to connect to the destination
4529// server. There's no standard for what a proxy should do to indicate a blocked
4530// site.
4531TEST_F(HttpNetworkTransactionTest,
4532 AuthAllowsDefaultCredentialsTunnelConnectionClosesBeforeBody) {
4533 HttpRequestInfo request;
4534 request.method = "GET";
4535 request.url = GURL("https://www.example.org/");
4536 request.traffic_annotation =
4537 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4538
4539 // Configure against proxy server "myproxy:70".
4540 session_deps_.proxy_resolution_service =
4541 ProxyResolutionService::CreateFixedFromPacResult(
4542 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4543
Steven Valdez0ef94d02018-11-19 23:28:134544 // When TLS 1.3 is enabled, spurious connections are made as part of the SSL
4545 // version interference probes.
4546 // TODO(crbug.com/906668): Correctly handle version interference probes to
4547 // test TLS 1.3.
4548 SSLConfig config;
4549 config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
4550 session_deps_.ssl_config_service =
4551 std::make_unique<TestSSLConfigService>(config);
4552
Asanka Herathbc3f8f62018-11-16 23:08:304553 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
4554 auth_handler_factory->set_do_init_from_challenge(true);
4555
4556 // Create two mock AuthHandlers. This is because the transaction gets retried
4557 // after the first ERR_CONNECTION_CLOSED since it's ambiguous whether there
4558 // was a real network error.
4559 //
4560 // The handlers support both default and explicit credentials. The retry
4561 // mentioned above should be able to reuse the default identity. Thus there
4562 // should never be a need to prompt for explicit credentials.
4563 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
4564 mock_handler->set_allows_default_credentials(true);
4565 mock_handler->set_allows_explicit_credentials(true);
4566 mock_handler->set_connection_based(true);
4567 auth_handler_factory->AddMockHandler(mock_handler.release(),
4568 HttpAuth::AUTH_PROXY);
4569 mock_handler = std::make_unique<HttpAuthHandlerMock>();
4570 mock_handler->set_allows_default_credentials(true);
4571 mock_handler->set_allows_explicit_credentials(true);
4572 mock_handler->set_connection_based(true);
4573 auth_handler_factory->AddMockHandler(mock_handler.release(),
4574 HttpAuth::AUTH_PROXY);
4575 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4576
4577 NetLog net_log;
4578 session_deps_.net_log = &net_log;
4579 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4580
4581 // Data for both sockets.
4582 //
4583 // Writes are for the tunnel establishment attempts and the
4584 // authentication handshake.
4585 MockWrite data_writes1[] = {
4586 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4587 "Host: www.example.org:443\r\n"
4588 "Proxy-Connection: keep-alive\r\n\r\n"),
4589
4590 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4591 "Host: www.example.org:443\r\n"
4592 "Proxy-Connection: keep-alive\r\n"
4593 "Proxy-Authorization: auth_token\r\n\r\n"),
4594
4595 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4596 "Host: www.example.org:443\r\n"
4597 "Proxy-Connection: keep-alive\r\n"
4598 "Proxy-Authorization: auth_token\r\n\r\n"),
4599 };
4600
4601 // The server side of the authentication handshake. Note that the response to
4602 // the final CONNECT request is ERR_CONNECTION_CLOSED.
4603 MockRead data_reads1[] = {
4604 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4605 MockRead("Content-Length: 0\r\n"),
4606 MockRead("Proxy-Connection: keep-alive\r\n"),
4607 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4608
4609 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4610 MockRead("Content-Length: 0\r\n"),
4611 MockRead("Proxy-Connection: keep-alive\r\n"),
4612 MockRead("Proxy-Authenticate: Mock foo\r\n\r\n"),
4613
4614 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4615 };
4616
4617 StaticSocketDataProvider data1(data_reads1, data_writes1);
4618 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4619
4620 // The second socket is for the reconnection attempt. Data is identical to the
4621 // first attempt.
4622 StaticSocketDataProvider data2(data_reads1, data_writes1);
4623 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4624
4625 auto trans =
4626 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4627
4628 TestCompletionCallback callback;
4629 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4630
4631 // Two rounds per handshake. After one retry, the error is propagated up the
4632 // stack.
4633 for (int i = 0; i < 4; ++i) {
4634 EXPECT_THAT(callback.GetResult(rv), IsOk());
4635
4636 const HttpResponseInfo* response = trans->GetResponseInfo();
4637 ASSERT_TRUE(response);
4638 ASSERT_TRUE(response->headers);
4639 EXPECT_EQ(407, response->headers->response_code());
4640 ASSERT_TRUE(trans->IsReadyToRestartForAuth());
4641
4642 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4643 }
4644
4645 // One shall be the number thou shalt retry, and the number of the retrying
4646 // shall be one. Two shalt thou not retry, neither retry thou zero, excepting
4647 // that thou then proceed to one. Three is right out. Once the number one,
4648 // being the first number, be reached, then lobbest thou thy
4649 // ERR_CONNECTION_CLOSED towards they network transaction, who shall snuff it.
4650 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.GetResult(rv));
4651
4652 trans.reset();
4653 session->CloseAllConnections();
4654}
4655
mmenke2a1781d2015-10-07 19:25:334656// Test a proxy auth scheme that allows default credentials and a proxy server
4657// that hangs up when credentials are initially sent, and sends a challenge
4658// again they are retried.
bncd16676a2016-07-20 16:23:014659TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334660 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4661 HttpRequestInfo request;
4662 request.method = "GET";
4663 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104664 request.traffic_annotation =
4665 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334666
4667 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594668 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494669 ProxyResolutionService::CreateFixedFromPacResult(
4670 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334671
Jeremy Roman0579ed62017-08-29 15:56:194672 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334673 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194674 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334675 mock_handler->set_allows_default_credentials(true);
4676 auth_handler_factory->AddMockHandler(mock_handler.release(),
4677 HttpAuth::AUTH_PROXY);
4678 // Add another handler for the second challenge. It supports default
4679 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194680 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334681 mock_handler->set_allows_default_credentials(true);
4682 auth_handler_factory->AddMockHandler(mock_handler.release(),
4683 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484684 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334685
4686 // Add NetLog just so can verify load timing information gets a NetLog ID.
4687 NetLog net_log;
4688 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094689 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334690
4691 // Should try to establish tunnel.
4692 MockWrite data_writes1[] = {
4693 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174694 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334695 "Proxy-Connection: keep-alive\r\n\r\n"),
4696 };
4697
4698 // The proxy responds to the connect with a 407, using a non-persistent
4699 // connection.
4700 MockRead data_reads1[] = {
4701 // No credentials.
4702 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4703 MockRead("Proxy-Authenticate: Mock\r\n"),
4704 MockRead("Proxy-Connection: close\r\n\r\n"),
4705 };
4706
4707 // Since the first connection was closed, need to establish another once given
4708 // credentials.
4709 MockWrite data_writes2[] = {
4710 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174711 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334712 "Proxy-Connection: keep-alive\r\n"
4713 "Proxy-Authorization: auth_token\r\n\r\n"),
4714 };
4715
4716 MockRead data_reads2[] = {
4717 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4718 MockRead("Proxy-Authenticate: Mock\r\n"),
4719 MockRead("Proxy-Connection: close\r\n\r\n"),
4720 };
4721
Ryan Sleevib8d7ea02018-05-07 20:01:014722 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334723 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014724 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334725 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4726 SSLSocketDataProvider ssl(ASYNC, OK);
4727 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4728
bnc87dcefc2017-05-25 12:47:584729 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194730 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334731
4732 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204733 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014734 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334735
4736 const HttpResponseInfo* response = trans->GetResponseInfo();
4737 ASSERT_TRUE(response);
4738 ASSERT_TRUE(response->headers);
4739 EXPECT_EQ(407, response->headers->response_code());
4740 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4741 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584742 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334743
4744 LoadTimingInfo load_timing_info;
4745 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4746
4747 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014748 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334749 response = trans->GetResponseInfo();
4750 ASSERT_TRUE(response);
4751 ASSERT_TRUE(response->headers);
4752 EXPECT_EQ(407, response->headers->response_code());
4753 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584754 EXPECT_TRUE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334755
4756 trans.reset();
4757 session->CloseAllConnections();
4758}
4759
asankae2257db2016-10-11 22:03:164760// A more nuanced test than GenerateAuthToken test which asserts that
4761// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4762// unnecessarily invalidated, and that if the server co-operates, the
4763// authentication handshake can continue with the same scheme but with a
4764// different identity.
4765TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4766 HttpRequestInfo request;
4767 request.method = "GET";
4768 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104769 request.traffic_annotation =
4770 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164771
Jeremy Roman0579ed62017-08-29 15:56:194772 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164773 auth_handler_factory->set_do_init_from_challenge(true);
4774
4775 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194776 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164777 mock_handler->set_allows_default_credentials(true);
4778 mock_handler->set_allows_explicit_credentials(true);
4779 mock_handler->set_connection_based(true);
4780 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4781 auth_handler_factory->AddMockHandler(mock_handler.release(),
4782 HttpAuth::AUTH_SERVER);
4783
4784 // Add another handler for the second challenge. It supports default
4785 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194786 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164787 mock_handler->set_allows_default_credentials(true);
4788 mock_handler->set_allows_explicit_credentials(true);
4789 mock_handler->set_connection_based(true);
4790 auth_handler_factory->AddMockHandler(mock_handler.release(),
4791 HttpAuth::AUTH_SERVER);
4792 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4793
4794 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4795
4796 MockWrite data_writes1[] = {
4797 MockWrite("GET / HTTP/1.1\r\n"
4798 "Host: www.example.org\r\n"
4799 "Connection: keep-alive\r\n\r\n"),
4800 };
4801
4802 MockRead data_reads1[] = {
4803 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4804 "WWW-Authenticate: Mock\r\n"
4805 "Connection: keep-alive\r\n\r\n"),
4806 };
4807
4808 // Identical to data_writes1[]. The AuthHandler encounters a
4809 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4810 // transaction procceds without an authorization header.
4811 MockWrite data_writes2[] = {
4812 MockWrite("GET / HTTP/1.1\r\n"
4813 "Host: www.example.org\r\n"
4814 "Connection: keep-alive\r\n\r\n"),
4815 };
4816
4817 MockRead data_reads2[] = {
4818 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4819 "WWW-Authenticate: Mock\r\n"
4820 "Connection: keep-alive\r\n\r\n"),
4821 };
4822
4823 MockWrite data_writes3[] = {
4824 MockWrite("GET / HTTP/1.1\r\n"
4825 "Host: www.example.org\r\n"
4826 "Connection: keep-alive\r\n"
4827 "Authorization: auth_token\r\n\r\n"),
4828 };
4829
4830 MockRead data_reads3[] = {
4831 MockRead("HTTP/1.1 200 OK\r\n"
4832 "Content-Length: 5\r\n"
4833 "Content-Type: text/plain\r\n"
4834 "Connection: keep-alive\r\n\r\n"
4835 "Hello"),
4836 };
4837
Ryan Sleevib8d7ea02018-05-07 20:01:014838 StaticSocketDataProvider data1(data_reads1, data_writes1);
asankae2257db2016-10-11 22:03:164839 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4840
Ryan Sleevib8d7ea02018-05-07 20:01:014841 StaticSocketDataProvider data2(data_reads2, data_writes2);
asankae2257db2016-10-11 22:03:164842 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4843
Ryan Sleevib8d7ea02018-05-07 20:01:014844 StaticSocketDataProvider data3(data_reads3, data_writes3);
asankae2257db2016-10-11 22:03:164845 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4846
bnc87dcefc2017-05-25 12:47:584847 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194848 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164849
4850 TestCompletionCallback callback;
4851 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4852 EXPECT_THAT(callback.GetResult(rv), IsOk());
4853
4854 const HttpResponseInfo* response = trans->GetResponseInfo();
4855 ASSERT_TRUE(response);
4856 ASSERT_TRUE(response->headers);
4857 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4858
4859 // The following three tests assert that an authentication challenge was
4860 // received and that the stack is ready to respond to the challenge using
4861 // ambient credentials.
4862 EXPECT_EQ(401, response->headers->response_code());
4863 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584864 EXPECT_FALSE(response->auth_challenge.has_value());
asankae2257db2016-10-11 22:03:164865
4866 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4867 EXPECT_THAT(callback.GetResult(rv), IsOk());
4868 response = trans->GetResponseInfo();
4869 ASSERT_TRUE(response);
4870 ASSERT_TRUE(response->headers);
4871
4872 // The following three tests assert that an authentication challenge was
4873 // received and that the stack needs explicit credentials before it is ready
4874 // to respond to the challenge.
4875 EXPECT_EQ(401, response->headers->response_code());
4876 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584877 EXPECT_TRUE(response->auth_challenge.has_value());
asankae2257db2016-10-11 22:03:164878
4879 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4880 EXPECT_THAT(callback.GetResult(rv), IsOk());
4881 response = trans->GetResponseInfo();
4882 ASSERT_TRUE(response);
4883 ASSERT_TRUE(response->headers);
4884 EXPECT_EQ(200, response->headers->response_code());
4885
4886 trans.reset();
4887 session->CloseAllConnections();
4888}
4889
Matt Menked1eb6d42018-01-17 04:54:064890// Proxy resolver that returns a proxy with the same host and port for different
4891// schemes, based on the path of the URL being requests.
4892class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4893 public:
4894 SameProxyWithDifferentSchemesProxyResolver() {}
4895 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4896
4897 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4898
4899 static HostPortPair ProxyHostPortPair() {
4900 return HostPortPair::FromString(ProxyHostPortPairAsString());
4901 }
4902
4903 // ProxyResolver implementation.
4904 int GetProxyForURL(const GURL& url,
4905 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:174906 CompletionOnceCallback callback,
Matt Menked1eb6d42018-01-17 04:54:064907 std::unique_ptr<Request>* request,
4908 const NetLogWithSource& /*net_log*/) override {
4909 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574910 results->set_traffic_annotation(
4911 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064912 if (url.path() == "/socks4") {
4913 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4914 return OK;
4915 }
4916 if (url.path() == "/socks5") {
4917 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4918 return OK;
4919 }
4920 if (url.path() == "/http") {
4921 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4922 return OK;
4923 }
4924 if (url.path() == "/https") {
4925 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4926 return OK;
4927 }
Matt Menkee8648fa2019-01-17 16:47:074928 if (url.path() == "/https_trusted") {
4929 results->UseProxyServer(ProxyServer(ProxyServer::SCHEME_HTTPS,
4930 ProxyHostPortPair(),
4931 true /* is_trusted_proxy */));
4932 return OK;
4933 }
Matt Menked1eb6d42018-01-17 04:54:064934 NOTREACHED();
4935 return ERR_NOT_IMPLEMENTED;
4936 }
4937
4938 private:
4939 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4940};
4941
4942class SameProxyWithDifferentSchemesProxyResolverFactory
4943 : public ProxyResolverFactory {
4944 public:
4945 SameProxyWithDifferentSchemesProxyResolverFactory()
4946 : ProxyResolverFactory(false) {}
4947
Lily Houghton99597862018-03-07 16:40:424948 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4949 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:174950 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:424951 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064952 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4953 return OK;
4954 }
4955
4956 private:
4957 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4958};
4959
4960// Check that when different proxy schemes are all applied to a proxy at the
Matt Menkee8648fa2019-01-17 16:47:074961// same address, the connections are not grouped together. i.e., a request to
Matt Menked1eb6d42018-01-17 04:54:064962// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4963// request to foo.com using proxy.com as an HTTP proxy.
4964TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494965 session_deps_.proxy_resolution_service =
4966 std::make_unique<ProxyResolutionService>(
4967 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4968 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4969 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4970 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064971
4972 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4973
4974 MockWrite socks_writes[] = {
4975 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4976 kSOCKS4OkRequestLocalHostPort80Length),
4977 MockWrite(SYNCHRONOUS,
4978 "GET /socks4 HTTP/1.1\r\n"
4979 "Host: test\r\n"
4980 "Connection: keep-alive\r\n\r\n"),
4981 };
4982 MockRead socks_reads[] = {
4983 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4984 MockRead("HTTP/1.0 200 OK\r\n"
4985 "Connection: keep-alive\r\n"
4986 "Content-Length: 15\r\n\r\n"
4987 "SOCKS4 Response"),
4988 };
Ryan Sleevib8d7ea02018-05-07 20:01:014989 StaticSocketDataProvider socks_data(socks_reads, socks_writes);
Matt Menked1eb6d42018-01-17 04:54:064990 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4991
4992 const char kSOCKS5Request[] = {
4993 0x05, // Version
4994 0x01, // Command (CONNECT)
4995 0x00, // Reserved
4996 0x03, // Address type (DOMAINNAME)
4997 0x04, // Length of domain (4)
4998 't', 'e', 's', 't', // Domain string
4999 0x00, 0x50, // 16-bit port (80)
5000 };
5001 MockWrite socks5_writes[] = {
5002 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Avi Drissman4365a4782018-12-28 19:26:245003 MockWrite(ASYNC, kSOCKS5Request, base::size(kSOCKS5Request)),
Matt Menked1eb6d42018-01-17 04:54:065004 MockWrite(SYNCHRONOUS,
5005 "GET /socks5 HTTP/1.1\r\n"
5006 "Host: test\r\n"
5007 "Connection: keep-alive\r\n\r\n"),
5008 };
5009 MockRead socks5_reads[] = {
5010 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
5011 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
5012 MockRead("HTTP/1.0 200 OK\r\n"
5013 "Connection: keep-alive\r\n"
5014 "Content-Length: 15\r\n\r\n"
5015 "SOCKS5 Response"),
5016 };
Ryan Sleevib8d7ea02018-05-07 20:01:015017 StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
Matt Menked1eb6d42018-01-17 04:54:065018 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
5019
5020 MockWrite http_writes[] = {
5021 MockWrite(SYNCHRONOUS,
5022 "GET http://test/http HTTP/1.1\r\n"
5023 "Host: test\r\n"
5024 "Proxy-Connection: keep-alive\r\n\r\n"),
5025 };
5026 MockRead http_reads[] = {
5027 MockRead("HTTP/1.1 200 OK\r\n"
5028 "Proxy-Connection: keep-alive\r\n"
5029 "Content-Length: 13\r\n\r\n"
5030 "HTTP Response"),
5031 };
Ryan Sleevib8d7ea02018-05-07 20:01:015032 StaticSocketDataProvider http_data(http_reads, http_writes);
Matt Menked1eb6d42018-01-17 04:54:065033 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
5034
5035 MockWrite https_writes[] = {
5036 MockWrite(SYNCHRONOUS,
5037 "GET http://test/https HTTP/1.1\r\n"
5038 "Host: test\r\n"
5039 "Proxy-Connection: keep-alive\r\n\r\n"),
5040 };
5041 MockRead https_reads[] = {
5042 MockRead("HTTP/1.1 200 OK\r\n"
5043 "Proxy-Connection: keep-alive\r\n"
5044 "Content-Length: 14\r\n\r\n"
5045 "HTTPS Response"),
5046 };
Ryan Sleevib8d7ea02018-05-07 20:01:015047 StaticSocketDataProvider https_data(https_reads, https_writes);
Matt Menked1eb6d42018-01-17 04:54:065048 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
5049 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
5050 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5051
Matt Menkee8648fa2019-01-17 16:47:075052 MockWrite https_trusted_writes[] = {
5053 MockWrite(SYNCHRONOUS,
5054 "GET http://test/https_trusted HTTP/1.1\r\n"
5055 "Host: test\r\n"
5056 "Proxy-Connection: keep-alive\r\n\r\n"),
5057 };
5058 MockRead https_trusted_reads[] = {
5059 MockRead("HTTP/1.1 200 OK\r\n"
5060 "Proxy-Connection: keep-alive\r\n"
5061 "Content-Length: 22\r\n\r\n"
5062 "HTTPS Trusted Response"),
5063 };
5064 StaticSocketDataProvider trusted_https_data(https_trusted_reads,
5065 https_trusted_writes);
5066 session_deps_.socket_factory->AddSocketDataProvider(&trusted_https_data);
5067 SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
5068 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
5069
Matt Menked1eb6d42018-01-17 04:54:065070 struct TestCase {
5071 GURL url;
5072 std::string expected_response;
Matt Menkee8648fa2019-01-17 16:47:075073 // How many idle sockets there should be in the SOCKS 4/5 proxy socket pools
Matt Menked1eb6d42018-01-17 04:54:065074 // after the test.
Matt Menkee8648fa2019-01-17 16:47:075075 int expected_idle_socks4_sockets;
5076 int expected_idle_socks5_sockets;
5077 // How many idle sockets there should be in the HTTP/HTTPS proxy socket
5078 // pools after the test.
Matt Menked1eb6d42018-01-17 04:54:065079 int expected_idle_http_sockets;
Matt Menkee8648fa2019-01-17 16:47:075080 int expected_idle_https_sockets;
5081 // How many idle sockets there should be in the HTTPS proxy socket pool with
5082 // the ProxyServer's |is_trusted_proxy| bit set after the test.
5083 int expected_idle_trusted_https_sockets;
Matt Menked1eb6d42018-01-17 04:54:065084 } const kTestCases[] = {
Matt Menkee8648fa2019-01-17 16:47:075085 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0, 0, 0, 0},
5086 {GURL("http://test/socks5"), "SOCKS5 Response", 1, 1, 0, 0, 0},
5087 {GURL("http://test/http"), "HTTP Response", 1, 1, 1, 0, 0},
5088 {GURL("http://test/https"), "HTTPS Response", 1, 1, 1, 1, 0},
5089 {GURL("http://test/https_trusted"), "HTTPS Trusted Response", 1, 1, 1, 1,
5090 1},
Matt Menked1eb6d42018-01-17 04:54:065091 };
5092
5093 for (const auto& test_case : kTestCases) {
5094 HttpRequestInfo request;
5095 request.method = "GET";
5096 request.url = test_case.url;
Ramin Halavatib5e433e62018-02-07 07:41:105097 request.traffic_annotation =
5098 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:065099 std::unique_ptr<HttpNetworkTransaction> trans =
5100 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
5101 session.get());
5102 TestCompletionCallback callback;
5103 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5104 EXPECT_THAT(callback.GetResult(rv), IsOk());
5105
5106 const HttpResponseInfo* response = trans->GetResponseInfo();
5107 ASSERT_TRUE(response);
5108 ASSERT_TRUE(response->headers);
5109 EXPECT_EQ(200, response->headers->response_code());
5110 std::string response_data;
5111 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
5112 EXPECT_EQ(test_case.expected_response, response_data);
5113
5114 // Return the socket to the socket pool, so can make sure it's not used for
5115 // the next requests.
5116 trans.reset();
5117 base::RunLoop().RunUntilIdle();
5118
5119 // Check the number of idle sockets in the pool, to make sure that used
5120 // sockets are indeed being returned to the socket pool. If each request
5121 // doesn't return an idle socket to the pool, the test would incorrectly
5122 // pass.
Matt Menkee8648fa2019-01-17 16:47:075123 EXPECT_EQ(test_case.expected_idle_socks4_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_SOCKS4,
5128 SameProxyWithDifferentSchemesProxyResolver::
5129 ProxyHostPortPair()))
5130 ->IdleSocketCount());
5131 EXPECT_EQ(test_case.expected_idle_socks5_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_SOCKS5,
5136 SameProxyWithDifferentSchemesProxyResolver::
5137 ProxyHostPortPair()))
5138 ->IdleSocketCount());
5139 EXPECT_EQ(test_case.expected_idle_http_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_HTTP,
5144 SameProxyWithDifferentSchemesProxyResolver::
5145 ProxyHostPortPair()))
5146 ->IdleSocketCount());
5147 EXPECT_EQ(test_case.expected_idle_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 ->IdleSocketCount());
5155 EXPECT_EQ(test_case.expected_idle_trusted_https_sockets,
5156 session
Matt Menked23ab952019-03-06 00:24:405157 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075158 HttpNetworkSession::NORMAL_SOCKET_POOL,
5159 ProxyServer(ProxyServer::SCHEME_HTTPS,
5160 SameProxyWithDifferentSchemesProxyResolver::
5161 ProxyHostPortPair(),
5162 true /* is_trusted_proxy */))
5163 ->IdleSocketCount());
Matt Menked1eb6d42018-01-17 04:54:065164 }
5165}
5166
[email protected]029c83b62013-01-24 05:28:205167// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:015168TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205169 HttpRequestInfo request1;
5170 request1.method = "GET";
bncce36dca22015-04-21 22:11:235171 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:105172 request1.traffic_annotation =
5173 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205174
5175 HttpRequestInfo request2;
5176 request2.method = "GET";
bncce36dca22015-04-21 22:11:235177 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:105178 request2.traffic_annotation =
5179 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205180
5181 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495182 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5183 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515184 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075185 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095186 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205187
5188 // Since we have proxy, should try to establish tunnel.
5189 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175190 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5191 "Host: www.example.org:443\r\n"
5192 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205193
rsleevidb16bb02015-11-12 23:47:175194 MockWrite("GET /1 HTTP/1.1\r\n"
5195 "Host: www.example.org\r\n"
5196 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205197
rsleevidb16bb02015-11-12 23:47:175198 MockWrite("GET /2 HTTP/1.1\r\n"
5199 "Host: www.example.org\r\n"
5200 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205201 };
5202
5203 // The proxy responds to the connect with a 407, using a persistent
5204 // connection.
5205 MockRead data_reads1[] = {
5206 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5207
5208 MockRead("HTTP/1.1 200 OK\r\n"),
5209 MockRead("Content-Length: 1\r\n\r\n"),
5210 MockRead(SYNCHRONOUS, "1"),
5211
5212 MockRead("HTTP/1.1 200 OK\r\n"),
5213 MockRead("Content-Length: 2\r\n\r\n"),
5214 MockRead(SYNCHRONOUS, "22"),
5215 };
5216
Ryan Sleevib8d7ea02018-05-07 20:01:015217 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075218 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205219 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075220 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205221
5222 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585223 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195224 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205225
5226 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015227 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205228
5229 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015230 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205231
5232 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525233 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:475234 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:525235 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205236 EXPECT_EQ(1, response1->headers->GetContentLength());
5237
5238 LoadTimingInfo load_timing_info1;
5239 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5240 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
5241
5242 trans1.reset();
5243
5244 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585245 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195246 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205247
5248 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015249 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205250
5251 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015252 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205253
5254 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525255 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:475256 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:525257 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205258 EXPECT_EQ(2, response2->headers->GetContentLength());
5259
5260 LoadTimingInfo load_timing_info2;
5261 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5262 TestLoadTimingReused(load_timing_info2);
5263
5264 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5265
5266 trans2.reset();
5267 session->CloseAllConnections();
5268}
5269
5270// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:015271TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205272 HttpRequestInfo request1;
5273 request1.method = "GET";
bncce36dca22015-04-21 22:11:235274 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:105275 request1.traffic_annotation =
5276 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205277
5278 HttpRequestInfo request2;
5279 request2.method = "GET";
bncce36dca22015-04-21 22:11:235280 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:105281 request2.traffic_annotation =
5282 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205283
5284 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595285 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:495286 ProxyResolutionService::CreateFixedFromPacResult(
5287 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515288 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075289 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095290 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205291
5292 // Since we have proxy, should try to establish tunnel.
5293 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175294 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5295 "Host: www.example.org:443\r\n"
5296 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205297
rsleevidb16bb02015-11-12 23:47:175298 MockWrite("GET /1 HTTP/1.1\r\n"
5299 "Host: www.example.org\r\n"
5300 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205301
rsleevidb16bb02015-11-12 23:47:175302 MockWrite("GET /2 HTTP/1.1\r\n"
5303 "Host: www.example.org\r\n"
5304 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205305 };
5306
5307 // The proxy responds to the connect with a 407, using a persistent
5308 // connection.
5309 MockRead data_reads1[] = {
5310 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5311
5312 MockRead("HTTP/1.1 200 OK\r\n"),
5313 MockRead("Content-Length: 1\r\n\r\n"),
5314 MockRead(SYNCHRONOUS, "1"),
5315
5316 MockRead("HTTP/1.1 200 OK\r\n"),
5317 MockRead("Content-Length: 2\r\n\r\n"),
5318 MockRead(SYNCHRONOUS, "22"),
5319 };
5320
Ryan Sleevib8d7ea02018-05-07 20:01:015321 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075322 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205323 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205325
5326 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585327 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195328 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205329
5330 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015331 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205332
5333 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015334 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205335
5336 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525337 ASSERT_TRUE(response1);
5338 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205339 EXPECT_EQ(1, response1->headers->GetContentLength());
5340
5341 LoadTimingInfo load_timing_info1;
5342 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5343 TestLoadTimingNotReusedWithPac(load_timing_info1,
5344 CONNECT_TIMING_HAS_SSL_TIMES);
5345
5346 trans1.reset();
5347
5348 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585349 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195350 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205351
5352 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015353 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205354
5355 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015356 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205357
5358 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525359 ASSERT_TRUE(response2);
5360 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205361 EXPECT_EQ(2, response2->headers->GetContentLength());
5362
5363 LoadTimingInfo load_timing_info2;
5364 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5365 TestLoadTimingReusedWithPac(load_timing_info2);
5366
5367 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5368
5369 trans2.reset();
5370 session->CloseAllConnections();
5371}
5372
[email protected]2df19bb2010-08-25 20:13:465373// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015374TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275375 HttpRequestInfo request;
5376 request.method = "GET";
bncce36dca22015-04-21 22:11:235377 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105378 request.traffic_annotation =
5379 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275380
[email protected]2df19bb2010-08-25 20:13:465381 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495382 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5383 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515384 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075385 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095386 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465387
[email protected]2df19bb2010-08-25 20:13:465388 // Since we have proxy, should use full url
5389 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235390 MockWrite(
5391 "GET http://www.example.org/ HTTP/1.1\r\n"
5392 "Host: www.example.org\r\n"
5393 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465394 };
5395
5396 MockRead data_reads1[] = {
5397 MockRead("HTTP/1.1 200 OK\r\n"),
5398 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5399 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065400 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465401 };
5402
Ryan Sleevib8d7ea02018-05-07 20:01:015403 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075404 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065405 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075406 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465407
[email protected]49639fa2011-12-20 23:22:415408 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465409
bnc691fda62016-08-12 00:43:165410 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505411
bnc691fda62016-08-12 00:43:165412 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015413 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465414
5415 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015416 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465417
[email protected]58e32bb2013-01-21 18:23:255418 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165419 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255420 TestLoadTimingNotReused(load_timing_info,
5421 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5422
bnc691fda62016-08-12 00:43:165423 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525424 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465425
tbansal2ecbbc72016-10-06 17:15:475426 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465427 EXPECT_TRUE(response->headers->IsKeepAlive());
5428 EXPECT_EQ(200, response->headers->response_code());
5429 EXPECT_EQ(100, response->headers->GetContentLength());
5430 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5431
5432 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:585433 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]2df19bb2010-08-25 20:13:465434}
5435
[email protected]7642b5ae2010-09-01 20:55:175436// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015437TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275438 HttpRequestInfo request;
5439 request.method = "GET";
bncce36dca22015-04-21 22:11:235440 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105441 request.traffic_annotation =
5442 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275443
[email protected]7642b5ae2010-09-01 20:55:175444 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495445 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5446 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515447 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075448 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095449 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175450
bncce36dca22015-04-21 22:11:235451 // fetch http://www.example.org/ via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135452 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455453 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415454 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175455
Ryan Hamilton0239aac2018-05-19 00:03:135456 spdy::SpdySerializedFrame resp(
5457 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5458 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175459 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415460 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175461 };
5462
Ryan Sleevib8d7ea02018-05-07 20:01:015463 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075464 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175465
[email protected]8ddf8322012-02-23 18:08:065466 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365467 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175469
[email protected]49639fa2011-12-20 23:22:415470 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175471
bnc691fda62016-08-12 00:43:165472 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505473
bnc691fda62016-08-12 00:43:165474 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175476
5477 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015478 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175479
[email protected]58e32bb2013-01-21 18:23:255480 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165481 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255482 TestLoadTimingNotReused(load_timing_info,
5483 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5484
bnc691fda62016-08-12 00:43:165485 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525486 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475487 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525488 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025489 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175490
5491 std::string response_data;
bnc691fda62016-08-12 00:43:165492 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235493 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175494}
5495
[email protected]1c173852014-06-19 12:51:505496// Verifies that a session which races and wins against the owning transaction
5497// (completing prior to host resolution), doesn't fail the transaction.
5498// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015499TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505500 HttpRequestInfo request;
5501 request.method = "GET";
bncce36dca22015-04-21 22:11:235502 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105503 request.traffic_annotation =
5504 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505505
5506 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495507 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5508 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515509 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505510 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095511 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505512
bncce36dca22015-04-21 22:11:235513 // Fetch http://www.example.org/ through the SPDY proxy.
Ryan Hamilton0239aac2018-05-19 00:03:135514 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455515 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415516 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505517
Raul Tambre94493c652019-03-11 17:18:355518 spdy::SpdySerializedFrame resp(
5519 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135520 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505521 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415522 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505523 };
5524
Ryan Sleevib8d7ea02018-05-07 20:01:015525 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]1c173852014-06-19 12:51:505526 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5527
5528 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365529 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505530 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5531
5532 TestCompletionCallback callback1;
5533
bnc691fda62016-08-12 00:43:165534 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505535
5536 // Stall the hostname resolution begun by the transaction.
[email protected]1c173852014-06-19 12:51:505537 session_deps_.host_resolver->set_ondemand_mode(true);
5538
bnc691fda62016-08-12 00:43:165539 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015540 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505541
5542 // Race a session to the proxy, which completes first.
5543 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045544 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:115545 PRIVACY_MODE_DISABLED,
5546 SpdySessionKey::IsProxySession::kTrue, SocketTag());
[email protected]1c173852014-06-19 12:51:505547 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525548 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505549
5550 // Unstall the resolution begun by the transaction.
5551 session_deps_.host_resolver->set_ondemand_mode(true);
5552 session_deps_.host_resolver->ResolveAllPending();
5553
5554 EXPECT_FALSE(callback1.have_result());
5555 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015556 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505557
bnc691fda62016-08-12 00:43:165558 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525559 ASSERT_TRUE(response);
5560 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025561 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505562
5563 std::string response_data;
bnc691fda62016-08-12 00:43:165564 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505565 EXPECT_EQ(kUploadData, response_data);
5566}
5567
[email protected]dc7bd1c52010-11-12 00:01:135568// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015569TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275570 HttpRequestInfo request;
5571 request.method = "GET";
bncce36dca22015-04-21 22:11:235572 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105573 request.traffic_annotation =
5574 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275575
[email protected]79cb5c12011-09-12 13:12:045576 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495577 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5578 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515579 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075580 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095581 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135582
[email protected]dc7bd1c52010-11-12 00:01:135583 // The first request will be a bare GET, the second request will be a
5584 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455585 spdy_util_.set_default_url(request.url);
Ryan Hamilton0239aac2018-05-19 00:03:135586 spdy::SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485587 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385588 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135589 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465590 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135591 };
Ryan Hamilton0239aac2018-05-19 00:03:135592 spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
Avi Drissman4365a4782018-12-28 19:26:245593 kExtraAuthorizationHeaders, base::size(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485594 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135595 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415596 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135597 };
5598
5599 // The first response is a 407 proxy authentication challenge, and the second
5600 // response will be a 200 response since the second request includes a valid
5601 // Authorization header.
5602 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465603 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135604 };
Ryan Hamilton0239aac2018-05-19 00:03:135605 spdy::SpdySerializedFrame resp_authentication(
5606 spdy_util_.ConstructSpdyReplyError(
5607 "407", kExtraAuthenticationHeaders,
Avi Drissman4365a4782018-12-28 19:26:245608 base::size(kExtraAuthenticationHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135609 spdy::SpdySerializedFrame body_authentication(
bncdf80d44fd2016-07-15 20:27:415610 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:135611 spdy::SpdySerializedFrame resp_data(
Raul Tambre94493c652019-03-11 17:18:355612 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:135613 spdy::SpdySerializedFrame body_data(
5614 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135615 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415616 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465617 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415618 CreateMockRead(resp_data, 4),
5619 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135620 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135621 };
5622
Ryan Sleevib8d7ea02018-05-07 20:01:015623 SequencedSocketData data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075624 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135625
[email protected]8ddf8322012-02-23 18:08:065626 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365627 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075628 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135629
[email protected]49639fa2011-12-20 23:22:415630 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135631
bnc691fda62016-08-12 00:43:165632 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135633
bnc691fda62016-08-12 00:43:165634 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015635 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135636
5637 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015638 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135639
bnc691fda62016-08-12 00:43:165640 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135641
wezca1070932016-05-26 20:30:525642 ASSERT_TRUE(response);
5643 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135644 EXPECT_EQ(407, response->headers->response_code());
5645 EXPECT_TRUE(response->was_fetched_via_spdy);
Emily Starkf2c9bbd2019-04-09 17:08:585646 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
[email protected]dc7bd1c52010-11-12 00:01:135647
[email protected]49639fa2011-12-20 23:22:415648 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135649
bnc691fda62016-08-12 00:43:165650 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135652
5653 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015654 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135655
bnc691fda62016-08-12 00:43:165656 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135657
wezca1070932016-05-26 20:30:525658 ASSERT_TRUE(response_restart);
5659 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135660 EXPECT_EQ(200, response_restart->headers->response_code());
5661 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:585662 EXPECT_FALSE(response_restart->auth_challenge.has_value());
[email protected]dc7bd1c52010-11-12 00:01:135663}
5664
[email protected]d9da5fe2010-10-13 22:37:165665// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015666TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275667 HttpRequestInfo request;
5668 request.method = "GET";
bncce36dca22015-04-21 22:11:235669 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105670 request.traffic_annotation =
5671 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275672
[email protected]d9da5fe2010-10-13 22:37:165673 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495674 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5675 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515676 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075677 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095678 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165679
bnc691fda62016-08-12 00:43:165680 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165681
bncce36dca22015-04-21 22:11:235682 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135683 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045684 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5685 HostPortPair("www.example.org", 443)));
bncce36dca22015-04-21 22:11:235686 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165687
bncce36dca22015-04-21 22:11:235688 const char get[] =
5689 "GET / HTTP/1.1\r\n"
5690 "Host: www.example.org\r\n"
5691 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135692 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195693 spdy_util_.ConstructSpdyDataFrame(1, get, false));
Ryan Hamilton0239aac2018-05-19 00:03:135694 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:355695 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165696 const char resp[] = "HTTP/1.1 200 OK\r\n"
5697 "Content-Length: 10\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135698 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195699 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:135700 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195701 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
Ryan Hamilton0239aac2018-05-19 00:03:135702 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415703 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045704
5705 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415706 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5707 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045708 };
5709
[email protected]d9da5fe2010-10-13 22:37:165710 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415711 CreateMockRead(conn_resp, 1, ASYNC),
5712 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5713 CreateMockRead(wrapped_body, 4, ASYNC),
5714 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135715 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165716 };
5717
Ryan Sleevib8d7ea02018-05-07 20:01:015718 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075719 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165720
[email protected]8ddf8322012-02-23 18:08:065721 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365722 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075723 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065724 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075725 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165726
[email protected]49639fa2011-12-20 23:22:415727 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165728
bnc691fda62016-08-12 00:43:165729 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015730 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165731
5732 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015733 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165734
[email protected]58e32bb2013-01-21 18:23:255735 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165736 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255737 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5738
bnc691fda62016-08-12 00:43:165739 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525740 ASSERT_TRUE(response);
5741 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165742 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5743
5744 std::string response_data;
bnc691fda62016-08-12 00:43:165745 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165746 EXPECT_EQ("1234567890", response_data);
5747}
5748
5749// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015750TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5751 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385752
[email protected]cb9bf6ca2011-01-28 13:15:275753 HttpRequestInfo request;
5754 request.method = "GET";
bncce36dca22015-04-21 22:11:235755 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105756 request.traffic_annotation =
5757 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275758
[email protected]d9da5fe2010-10-13 22:37:165759 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495760 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5761 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515762 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075763 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095764 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165765
bnc691fda62016-08-12 00:43:165766 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165767
bncce36dca22015-04-21 22:11:235768 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135769 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045770 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5771 HostPortPair("www.example.org", 443)));
bncce36dca22015-04-21 22:11:235772 // fetch https://www.example.org/ via SPDY
5773 const char kMyUrl[] = "https://www.example.org/";
Ryan Hamilton0239aac2018-05-19 00:03:135774 spdy::SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495775 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:135776 spdy::SpdySerializedFrame wrapped_get(
5777 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
5778 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:355779 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135780 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:355781 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135782 spdy::SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025783 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135784 spdy::SpdySerializedFrame body(
5785 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5786 spdy::SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025787 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135788 spdy::SpdySerializedFrame window_update_get_resp(
bncdf80d44fd2016-07-15 20:27:415789 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
Ryan Hamilton0239aac2018-05-19 00:03:135790 spdy::SpdySerializedFrame window_update_body(
bncdf80d44fd2016-07-15 20:27:415791 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045792
5793 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415794 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5795 CreateMockWrite(window_update_get_resp, 6),
5796 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045797 };
5798
[email protected]d9da5fe2010-10-13 22:37:165799 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415800 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095801 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415802 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5803 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135804 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165805 };
5806
Ryan Sleevib8d7ea02018-05-07 20:01:015807 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075808 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165809
[email protected]8ddf8322012-02-23 18:08:065810 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365811 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075812 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065813 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365814 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075815 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165816
[email protected]49639fa2011-12-20 23:22:415817 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165818
bnc691fda62016-08-12 00:43:165819 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165821
rch32320842015-05-16 15:57:095822 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555823 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095824 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595825 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165826 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015827 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165828
[email protected]58e32bb2013-01-21 18:23:255829 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165830 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255831 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5832
bnc691fda62016-08-12 00:43:165833 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525834 ASSERT_TRUE(response);
5835 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025836 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165837
5838 std::string response_data;
bnc691fda62016-08-12 00:43:165839 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235840 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165841}
5842
5843// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015844TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275845 HttpRequestInfo request;
5846 request.method = "GET";
bncce36dca22015-04-21 22:11:235847 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105848 request.traffic_annotation =
5849 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275850
[email protected]d9da5fe2010-10-13 22:37:165851 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495852 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5853 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515854 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075855 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095856 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165857
bnc691fda62016-08-12 00:43:165858 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165859
bncce36dca22015-04-21 22:11:235860 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135861 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045862 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5863 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135864 spdy::SpdySerializedFrame get(
5865 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165866
5867 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415868 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165869 };
5870
Ryan Hamilton0239aac2018-05-19 00:03:135871 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
5872 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165873 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415874 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165875 };
5876
Ryan Sleevib8d7ea02018-05-07 20:01:015877 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075878 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165879
[email protected]8ddf8322012-02-23 18:08:065880 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365881 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075882 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065883 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365884 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075885 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165886
[email protected]49639fa2011-12-20 23:22:415887 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165888
bnc691fda62016-08-12 00:43:165889 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015890 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165891
5892 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015893 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165894
ttuttle960fcbf2016-04-19 13:26:325895 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165896}
5897
Matt Menkecb2cd0982018-12-19 17:54:045898// Test the case where a proxied H2 session doesn't exist when an auth challenge
5899// is observed, but does exist by the time auth credentials are provided.
5900// Proxy-Connection: Close is used so that there's a second DNS lookup, which is
5901// what causes the existing H2 session to be noticed and reused.
5902TEST_F(HttpNetworkTransactionTest, ProxiedH2SessionAppearsDuringAuth) {
5903 ProxyConfig proxy_config;
5904 proxy_config.set_auto_detect(true);
5905 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
5906
5907 CapturingProxyResolver capturing_proxy_resolver;
5908 capturing_proxy_resolver.set_proxy_server(
5909 ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 70)));
5910 session_deps_.proxy_resolution_service =
5911 std::make_unique<ProxyResolutionService>(
5912 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
5913 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
5914 std::make_unique<CapturingProxyResolverFactory>(
5915 &capturing_proxy_resolver),
5916 nullptr);
5917
5918 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5919
5920 const char kMyUrl[] = "https://www.example.org/";
5921 spdy::SpdySerializedFrame get(spdy_util_.ConstructSpdyGet(kMyUrl, 1, LOWEST));
5922 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:355923 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menkecb2cd0982018-12-19 17:54:045924 spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
5925
5926 spdy_util_.UpdateWithStreamDestruction(1);
5927 spdy::SpdySerializedFrame get2(
5928 spdy_util_.ConstructSpdyGet(kMyUrl, 3, LOWEST));
5929 spdy::SpdySerializedFrame get_resp2(
Raul Tambre94493c652019-03-11 17:18:355930 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Matt Menkecb2cd0982018-12-19 17:54:045931 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
5932
5933 MockWrite auth_challenge_writes[] = {
5934 MockWrite(ASYNC, 0,
5935 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5936 "Host: www.example.org:443\r\n"
5937 "Proxy-Connection: keep-alive\r\n\r\n"),
5938 };
5939
5940 MockRead auth_challenge_reads[] = {
5941 MockRead(ASYNC, 1,
5942 "HTTP/1.1 407 Authentication Required\r\n"
5943 "Content-Length: 0\r\n"
5944 "Proxy-Connection: close\r\n"
5945 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
5946 };
5947
5948 MockWrite spdy_writes[] = {
5949 MockWrite(ASYNC, 0,
5950 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5951 "Host: www.example.org:443\r\n"
5952 "Proxy-Connection: keep-alive\r\n"
5953 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5954 CreateMockWrite(get, 2),
5955 CreateMockWrite(get2, 5),
5956 };
5957
5958 MockRead spdy_reads[] = {
5959 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
5960 CreateMockRead(get_resp, 3, ASYNC),
5961 CreateMockRead(body, 4, ASYNC),
5962 CreateMockRead(get_resp2, 6, ASYNC),
5963 CreateMockRead(body2, 7, ASYNC),
5964
5965 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 8),
5966 };
5967
5968 SequencedSocketData auth_challenge1(auth_challenge_reads,
5969 auth_challenge_writes);
5970 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge1);
5971
5972 SequencedSocketData auth_challenge2(auth_challenge_reads,
5973 auth_challenge_writes);
5974 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge2);
5975
5976 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
5977 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5978
5979 SSLSocketDataProvider ssl(ASYNC, OK);
5980 ssl.next_proto = kProtoHTTP2;
5981 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5982
5983 TestCompletionCallback callback;
5984 std::string response_data;
5985
5986 // Run first request until an auth challenge is observed.
5987 HttpRequestInfo request1;
5988 request1.method = "GET";
5989 request1.url = GURL(kMyUrl);
5990 request1.traffic_annotation =
5991 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5992 HttpNetworkTransaction trans1(LOWEST, session.get());
5993 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
5994 EXPECT_THAT(callback.GetResult(rv), IsOk());
5995 const HttpResponseInfo* response = trans1.GetResponseInfo();
5996 ASSERT_TRUE(response);
5997 ASSERT_TRUE(response->headers);
5998 EXPECT_EQ(407, response->headers->response_code());
5999 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:586000 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
Matt Menkecb2cd0982018-12-19 17:54:046001
6002 // Run second request until an auth challenge is observed.
6003 HttpRequestInfo request2;
6004 request2.method = "GET";
6005 request2.url = GURL(kMyUrl);
6006 request2.traffic_annotation =
6007 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6008 HttpNetworkTransaction trans2(LOWEST, session.get());
6009 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6010 EXPECT_THAT(callback.GetResult(rv), IsOk());
6011 response = trans2.GetResponseInfo();
6012 ASSERT_TRUE(response);
6013 ASSERT_TRUE(response->headers);
6014 EXPECT_EQ(407, response->headers->response_code());
6015 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:586016 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
Matt Menkecb2cd0982018-12-19 17:54:046017
6018 // Now provide credentials for the first request, and wait for it to complete.
6019 rv = trans1.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6020 rv = callback.GetResult(rv);
6021 EXPECT_THAT(rv, IsOk());
6022 response = trans1.GetResponseInfo();
6023 ASSERT_TRUE(response);
6024 ASSERT_TRUE(response->headers);
6025 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6026 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6027 EXPECT_EQ(kUploadData, response_data);
6028
6029 // Now provide credentials for the second request. It should notice the
6030 // existing session, and reuse it.
6031 rv = trans2.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6032 EXPECT_THAT(callback.GetResult(rv), IsOk());
6033 response = trans2.GetResponseInfo();
6034 ASSERT_TRUE(response);
6035 ASSERT_TRUE(response->headers);
6036 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6037 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6038 EXPECT_EQ(kUploadData, response_data);
6039}
6040
[email protected]f6c63db52013-02-02 00:35:226041// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6042// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:016043TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226044 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
6045 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496046 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6047 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516048 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076049 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096050 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506051 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226052
6053 HttpRequestInfo request1;
6054 request1.method = "GET";
bncce36dca22015-04-21 22:11:236055 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226056 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106057 request1.traffic_annotation =
6058 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226059
6060 HttpRequestInfo request2;
6061 request2.method = "GET";
bncce36dca22015-04-21 22:11:236062 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226063 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106064 request2.traffic_annotation =
6065 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226066
bncce36dca22015-04-21 22:11:236067 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136068 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046069 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6070 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136071 spdy::SpdySerializedFrame conn_resp1(
Raul Tambre94493c652019-03-11 17:18:356072 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226073
bncce36dca22015-04-21 22:11:236074 // Fetch https://www.example.org/ via HTTP.
6075 const char get1[] =
6076 "GET / HTTP/1.1\r\n"
6077 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226078 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136079 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196080 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226081 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6082 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136083 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196084 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136085 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196086 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136087 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416088 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226089
bncce36dca22015-04-21 22:11:236090 // CONNECT to mail.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136091 spdy::SpdyHeaderBlock connect2_block;
6092 connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
6093 connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
6094 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
Matt Menke6e879bd2019-03-18 17:26:046095 3, std::move(connect2_block), HttpProxyConnectJob::kH2QuicTunnelPriority,
6096 false));
[email protected]601e03f12014-04-06 16:26:396097
Ryan Hamilton0239aac2018-05-19 00:03:136098 spdy::SpdySerializedFrame conn_resp2(
Raul Tambre94493c652019-03-11 17:18:356099 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
[email protected]f6c63db52013-02-02 00:35:226100
bncce36dca22015-04-21 22:11:236101 // Fetch https://mail.example.org/ via HTTP.
6102 const char get2[] =
6103 "GET / HTTP/1.1\r\n"
6104 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226105 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136106 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196107 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:226108 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6109 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136110 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196111 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136112 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196113 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:226114
6115 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416116 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6117 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:226118 };
6119
6120 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416121 CreateMockRead(conn_resp1, 1, ASYNC),
6122 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
6123 CreateMockRead(wrapped_body1, 4, ASYNC),
6124 CreateMockRead(conn_resp2, 6, ASYNC),
6125 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
6126 CreateMockRead(wrapped_body2, 9, ASYNC),
6127 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:226128 };
6129
Ryan Sleevib8d7ea02018-05-07 20:01:016130 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506131 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226132
6133 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366134 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506135 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226136 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506137 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226138 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506139 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:226140
6141 TestCompletionCallback callback;
6142
bnc691fda62016-08-12 00:43:166143 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206144 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016145 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226146
6147 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166148 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:226149 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6150
bnc691fda62016-08-12 00:43:166151 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526152 ASSERT_TRUE(response);
6153 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226154 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6155
6156 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446157 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
bnc691fda62016-08-12 00:43:166158 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506159 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226160
bnc691fda62016-08-12 00:43:166161 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206162 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016163 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226164
6165 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166166 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226167 // Even though the SPDY connection is reused, a new tunnelled connection has
6168 // to be created, so the socket's load timing looks like a fresh connection.
6169 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
6170
6171 // The requests should have different IDs, since they each are using their own
6172 // separate stream.
6173 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6174
bnc691fda62016-08-12 00:43:166175 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506176 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226177}
6178
6179// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6180// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:016181TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226182 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
6183 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496184 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6185 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516186 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076187 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096188 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506189 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226190
6191 HttpRequestInfo request1;
6192 request1.method = "GET";
bncce36dca22015-04-21 22:11:236193 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226194 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106195 request1.traffic_annotation =
6196 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226197
6198 HttpRequestInfo request2;
6199 request2.method = "GET";
bncce36dca22015-04-21 22:11:236200 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:226201 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106202 request2.traffic_annotation =
6203 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226204
bncce36dca22015-04-21 22:11:236205 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136206 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046207 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6208 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136209 spdy::SpdySerializedFrame conn_resp1(
Raul Tambre94493c652019-03-11 17:18:356210 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226211
bncce36dca22015-04-21 22:11:236212 // Fetch https://www.example.org/ via HTTP.
6213 const char get1[] =
6214 "GET / HTTP/1.1\r\n"
6215 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226216 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136217 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196218 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226219 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6220 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136221 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196222 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136223 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196224 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136225 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416226 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226227
bncce36dca22015-04-21 22:11:236228 // Fetch https://www.example.org/2 via HTTP.
6229 const char get2[] =
6230 "GET /2 HTTP/1.1\r\n"
6231 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226232 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136233 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196234 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:226235 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6236 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136237 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196238 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136239 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196240 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:226241
6242 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416243 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6244 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:226245 };
6246
6247 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416248 CreateMockRead(conn_resp1, 1, ASYNC),
6249 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:466250 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416251 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:466252 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416253 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:226254 };
6255
Ryan Sleevib8d7ea02018-05-07 20:01:016256 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506257 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226258
6259 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366260 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506261 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226262 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506263 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226264
6265 TestCompletionCallback callback;
6266
bnc87dcefc2017-05-25 12:47:586267 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196268 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206269 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016270 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226271
6272 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016273 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226274
6275 LoadTimingInfo load_timing_info;
6276 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6277 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6278
6279 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526280 ASSERT_TRUE(response);
6281 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226282 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6283
6284 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446285 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
[email protected]90499482013-06-01 00:39:506286 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226287 trans.reset();
6288
bnc87dcefc2017-05-25 12:47:586289 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:196290 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206291 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016292 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226293
[email protected]f6c63db52013-02-02 00:35:226294 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016295 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226296
6297 LoadTimingInfo load_timing_info2;
6298 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
6299 TestLoadTimingReused(load_timing_info2);
6300
6301 // The requests should have the same ID.
6302 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6303
[email protected]90499482013-06-01 00:39:506304 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226305}
6306
6307// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
6308// Proxy to different servers.
bncd16676a2016-07-20 16:23:016309TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:226310 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496311 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6312 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516313 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076314 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096315 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506316 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226317
6318 HttpRequestInfo request1;
6319 request1.method = "GET";
bncce36dca22015-04-21 22:11:236320 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226321 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106322 request1.traffic_annotation =
6323 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226324
6325 HttpRequestInfo request2;
6326 request2.method = "GET";
bncce36dca22015-04-21 22:11:236327 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226328 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106329 request2.traffic_annotation =
6330 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226331
bncce36dca22015-04-21 22:11:236332 // http://www.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136333 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:236334 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136335 spdy::SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:156336 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136337 spdy::SpdySerializedFrame get_resp1(
Raul Tambre94493c652019-03-11 17:18:356338 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:136339 spdy::SpdySerializedFrame body1(
6340 spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:386341 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:226342
bncce36dca22015-04-21 22:11:236343 // http://mail.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136344 spdy::SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:236345 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136346 spdy::SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:156347 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136348 spdy::SpdySerializedFrame get_resp2(
Raul Tambre94493c652019-03-11 17:18:356349 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:136350 spdy::SpdySerializedFrame body2(
6351 spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:226352
6353 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416354 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:226355 };
6356
6357 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416358 CreateMockRead(get_resp1, 1, ASYNC),
6359 CreateMockRead(body1, 2, ASYNC),
6360 CreateMockRead(get_resp2, 4, ASYNC),
6361 CreateMockRead(body2, 5, ASYNC),
6362 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:226363 };
6364
Ryan Sleevib8d7ea02018-05-07 20:01:016365 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506366 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226367
6368 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366369 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506370 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226371
6372 TestCompletionCallback callback;
6373
bnc87dcefc2017-05-25 12:47:586374 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196375 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206376 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016377 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226378
6379 LoadTimingInfo load_timing_info;
6380 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6381 TestLoadTimingNotReused(load_timing_info,
6382 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6383
6384 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526385 ASSERT_TRUE(response);
6386 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:026387 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:226388
6389 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446390 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
mmenke11eb5152015-06-09 14:50:506391 rv = trans->Read(buf.get(), 256, callback.callback());
6392 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226393 // Delete the first request, so the second one can reuse the socket.
6394 trans.reset();
6395
bnc691fda62016-08-12 00:43:166396 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206397 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016398 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226399
6400 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166401 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226402 TestLoadTimingReused(load_timing_info2);
6403
6404 // The requests should have the same ID.
6405 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6406
bnc691fda62016-08-12 00:43:166407 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506408 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226409}
6410
Matt Menke2436b2f2018-12-11 18:07:116411// Test that an HTTP/2 CONNECT through an HTTPS Proxy to a HTTP/2 server and a
6412// direct (non-proxied) request to the proxy server are not pooled, as that
6413// would break socket pool isolation.
6414TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation1) {
6415 ProxyConfig proxy_config;
6416 proxy_config.set_auto_detect(true);
6417 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6418
6419 CapturingProxyResolver capturing_proxy_resolver;
6420 session_deps_.proxy_resolution_service =
6421 std::make_unique<ProxyResolutionService>(
6422 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6423 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6424 std::make_unique<CapturingProxyResolverFactory>(
6425 &capturing_proxy_resolver),
6426 nullptr);
6427
6428 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6429
6430 SpdyTestUtil spdy_util1;
6431 // CONNECT to www.example.org:443 via HTTP/2.
6432 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046433 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6434 HostPortPair("www.example.org", 443)));
Matt Menke2436b2f2018-12-11 18:07:116435 // fetch https://www.example.org/ via HTTP/2.
6436 const char kMyUrl[] = "https://www.example.org/";
6437 spdy::SpdySerializedFrame get(spdy_util1.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6438 spdy::SpdySerializedFrame wrapped_get(
6439 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6440 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:356441 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menke2436b2f2018-12-11 18:07:116442 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:356443 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menke2436b2f2018-12-11 18:07:116444 spdy::SpdySerializedFrame wrapped_get_resp(
6445 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6446 spdy::SpdySerializedFrame body(spdy_util1.ConstructSpdyDataFrame(1, true));
6447 spdy::SpdySerializedFrame wrapped_body(
6448 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6449 spdy::SpdySerializedFrame window_update_get_resp(
6450 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6451 spdy::SpdySerializedFrame window_update_body(
6452 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6453
6454 MockWrite spdy_writes1[] = {
6455 CreateMockWrite(connect, 0),
6456 CreateMockWrite(wrapped_get, 2),
6457 CreateMockWrite(window_update_get_resp, 6),
6458 CreateMockWrite(window_update_body, 7),
6459 };
6460
6461 MockRead spdy_reads1[] = {
6462 CreateMockRead(conn_resp, 1, ASYNC),
6463 MockRead(ASYNC, ERR_IO_PENDING, 3),
6464 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6465 CreateMockRead(wrapped_body, 5, ASYNC),
6466 MockRead(ASYNC, 0, 8),
6467 };
6468
6469 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6470 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6471
6472 // Fetch https://proxy:70/ via HTTP/2. Needs a new SpdyTestUtil, since it uses
6473 // a new pipe.
6474 SpdyTestUtil spdy_util2;
6475 spdy::SpdySerializedFrame req(
6476 spdy_util2.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6477 MockWrite spdy_writes2[] = {CreateMockWrite(req, 0)};
6478
6479 spdy::SpdySerializedFrame resp(
6480 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6481 spdy::SpdySerializedFrame data(spdy_util2.ConstructSpdyDataFrame(1, true));
6482 MockRead spdy_reads2[] = {
6483 CreateMockRead(resp, 1),
6484 CreateMockRead(data, 2),
6485 MockRead(ASYNC, 0, 3),
6486 };
6487 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6488 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6489
6490 SSLSocketDataProvider ssl(ASYNC, OK);
6491 ssl.next_proto = kProtoHTTP2;
6492 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6493 SSLSocketDataProvider ssl2(ASYNC, OK);
6494 ssl2.next_proto = kProtoHTTP2;
6495 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6496 SSLSocketDataProvider ssl3(ASYNC, OK);
6497 ssl3.next_proto = kProtoHTTP2;
6498 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6499
6500 TestCompletionCallback callback;
6501 std::string response_data;
6502
6503 // Make a request using proxy:70 as a HTTP/2 proxy.
6504 capturing_proxy_resolver.set_proxy_server(
6505 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6506 HttpRequestInfo request1;
6507 request1.method = "GET";
6508 request1.url = GURL("https://www.example.org/");
6509 request1.traffic_annotation =
6510 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6511
6512 HttpNetworkTransaction trans1(LOWEST, session.get());
6513 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
6514 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6515
6516 // Allow the SpdyProxyClientSocket's write callback to complete.
6517 base::RunLoop().RunUntilIdle();
6518 // Now allow the read of the response to complete.
6519 spdy_data1.Resume();
6520 rv = callback.WaitForResult();
6521 EXPECT_THAT(rv, IsOk());
6522
6523 const HttpResponseInfo* response = trans1.GetResponseInfo();
6524 ASSERT_TRUE(response);
6525 ASSERT_TRUE(response->headers);
6526 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6527
6528 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6529 EXPECT_EQ(kUploadData, response_data);
6530 RunUntilIdle();
6531
6532 // Make a direct HTTP/2 request to proxy:70.
6533 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6534 HttpRequestInfo request2;
6535 request2.method = "GET";
6536 request2.url = GURL("https://proxy:70/");
6537 request2.traffic_annotation =
6538 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6539 HttpNetworkTransaction trans2(LOWEST, session.get());
6540 EXPECT_THAT(callback.GetResult(trans2.Start(&request2, callback.callback(),
6541 NetLogWithSource())),
6542 IsOk());
6543 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6544}
6545
6546// Same as above, but reverse request order, since the code to check for an
6547// existing session is different for tunnels and direct connections.
6548TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation2) {
6549 // Configure against https proxy server "myproxy:80".
6550 ProxyConfig proxy_config;
6551 proxy_config.set_auto_detect(true);
6552 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6553
6554 CapturingProxyResolver capturing_proxy_resolver;
6555 session_deps_.proxy_resolution_service =
6556 std::make_unique<ProxyResolutionService>(
6557 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6558 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6559 std::make_unique<CapturingProxyResolverFactory>(
6560 &capturing_proxy_resolver),
6561 nullptr);
6562
6563 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6564 // Fetch https://proxy:70/ via HTTP/2.
6565 SpdyTestUtil spdy_util1;
6566 spdy::SpdySerializedFrame req(
6567 spdy_util1.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6568 MockWrite spdy_writes1[] = {CreateMockWrite(req, 0)};
6569
6570 spdy::SpdySerializedFrame resp(
6571 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
6572 spdy::SpdySerializedFrame data(spdy_util1.ConstructSpdyDataFrame(1, true));
6573 MockRead spdy_reads1[] = {
6574 CreateMockRead(resp, 1),
6575 CreateMockRead(data, 2),
6576 MockRead(ASYNC, 0, 3),
6577 };
6578 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6579 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6580
6581 SpdyTestUtil spdy_util2;
6582 // CONNECT to www.example.org:443 via HTTP/2.
6583 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046584 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6585 HostPortPair("www.example.org", 443)));
Matt Menke2436b2f2018-12-11 18:07:116586 // fetch https://www.example.org/ via HTTP/2.
6587 const char kMyUrl[] = "https://www.example.org/";
6588 spdy::SpdySerializedFrame get(spdy_util2.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6589 spdy::SpdySerializedFrame wrapped_get(
6590 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6591 spdy::SpdySerializedFrame conn_resp(
6592 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6593 spdy::SpdySerializedFrame get_resp(
6594 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6595 spdy::SpdySerializedFrame wrapped_get_resp(
6596 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6597 spdy::SpdySerializedFrame body(spdy_util2.ConstructSpdyDataFrame(1, true));
6598 spdy::SpdySerializedFrame wrapped_body(
6599 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6600 spdy::SpdySerializedFrame window_update_get_resp(
6601 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6602 spdy::SpdySerializedFrame window_update_body(
6603 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6604
6605 MockWrite spdy_writes2[] = {
6606 CreateMockWrite(connect, 0),
6607 CreateMockWrite(wrapped_get, 2),
6608 CreateMockWrite(window_update_get_resp, 6),
6609 CreateMockWrite(window_update_body, 7),
6610 };
6611
6612 MockRead spdy_reads2[] = {
6613 CreateMockRead(conn_resp, 1, ASYNC),
6614 MockRead(ASYNC, ERR_IO_PENDING, 3),
6615 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6616 CreateMockRead(wrapped_body, 5, ASYNC),
6617 MockRead(ASYNC, 0, 8),
6618 };
6619
6620 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6621 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6622
6623 SSLSocketDataProvider ssl(ASYNC, OK);
6624 ssl.next_proto = kProtoHTTP2;
6625 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6626 SSLSocketDataProvider ssl2(ASYNC, OK);
6627 ssl2.next_proto = kProtoHTTP2;
6628 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6629 SSLSocketDataProvider ssl3(ASYNC, OK);
6630 ssl3.next_proto = kProtoHTTP2;
6631 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6632
6633 TestCompletionCallback callback;
6634 std::string response_data;
6635
6636 // Make a direct HTTP/2 request to proxy:70.
6637 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6638 HttpRequestInfo request1;
6639 request1.method = "GET";
6640 request1.url = GURL("https://proxy:70/");
6641 request1.traffic_annotation =
6642 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6643 HttpNetworkTransaction trans1(LOWEST, session.get());
6644 EXPECT_THAT(callback.GetResult(trans1.Start(&request1, callback.callback(),
6645 NetLogWithSource())),
6646 IsOk());
6647 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6648 RunUntilIdle();
6649
6650 // Make a request using proxy:70 as a HTTP/2 proxy.
6651 capturing_proxy_resolver.set_proxy_server(
6652 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6653 HttpRequestInfo request2;
6654 request2.method = "GET";
6655 request2.url = GURL("https://www.example.org/");
6656 request2.traffic_annotation =
6657 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6658
6659 HttpNetworkTransaction trans2(LOWEST, session.get());
6660 int rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6661 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6662
6663 // Allow the SpdyProxyClientSocket's write callback to complete.
6664 base::RunLoop().RunUntilIdle();
6665 // Now allow the read of the response to complete.
6666 spdy_data2.Resume();
6667 rv = callback.WaitForResult();
6668 EXPECT_THAT(rv, IsOk());
6669
6670 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
6671 ASSERT_TRUE(response2);
6672 ASSERT_TRUE(response2->headers);
6673 EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
6674
6675 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6676 EXPECT_EQ(kUploadData, response_data);
6677}
6678
[email protected]2df19bb2010-08-25 20:13:466679// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:016680TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:466681 HttpRequestInfo request;
6682 request.method = "GET";
bncce36dca22015-04-21 22:11:236683 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466684 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296685 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:106686 request.traffic_annotation =
6687 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:466688
[email protected]79cb5c12011-09-12 13:12:046689 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496690 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6691 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516692 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076693 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096694 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276695
[email protected]2df19bb2010-08-25 20:13:466696 // Since we have proxy, should use full url
6697 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:166698 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6699 "Host: www.example.org\r\n"
6700 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466701
bnc691fda62016-08-12 00:43:166702 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:236703 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:166704 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6705 "Host: www.example.org\r\n"
6706 "Proxy-Connection: keep-alive\r\n"
6707 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466708 };
6709
6710 // The proxy responds to the GET with a 407, using a persistent
6711 // connection.
6712 MockRead data_reads1[] = {
6713 // No credentials.
6714 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6715 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6716 MockRead("Proxy-Connection: keep-alive\r\n"),
6717 MockRead("Content-Length: 0\r\n\r\n"),
6718
6719 MockRead("HTTP/1.1 200 OK\r\n"),
6720 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6721 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066722 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466723 };
6724
Ryan Sleevib8d7ea02018-05-07 20:01:016725 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:076726 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:066727 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076728 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466729
[email protected]49639fa2011-12-20 23:22:416730 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:466731
bnc691fda62016-08-12 00:43:166732 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506733
bnc691fda62016-08-12 00:43:166734 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:016735 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466736
6737 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016738 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466739
[email protected]58e32bb2013-01-21 18:23:256740 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166741 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256742 TestLoadTimingNotReused(load_timing_info,
6743 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6744
bnc691fda62016-08-12 00:43:166745 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526746 ASSERT_TRUE(response);
6747 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:466748 EXPECT_EQ(407, response->headers->response_code());
6749 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:586750 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
Wojciech Dzierżanowski0950c372019-04-02 19:29:506751 EXPECT_FALSE(response->did_use_http_auth);
[email protected]2df19bb2010-08-25 20:13:466752
[email protected]49639fa2011-12-20 23:22:416753 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:466754
bnc691fda62016-08-12 00:43:166755 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016756 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466757
6758 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016759 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466760
[email protected]58e32bb2013-01-21 18:23:256761 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:166762 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256763 // Retrying with HTTP AUTH is considered to be reusing a socket.
6764 TestLoadTimingReused(load_timing_info);
6765
bnc691fda62016-08-12 00:43:166766 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526767 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:466768
6769 EXPECT_TRUE(response->headers->IsKeepAlive());
6770 EXPECT_EQ(200, response->headers->response_code());
6771 EXPECT_EQ(100, response->headers->GetContentLength());
6772 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Wojciech Dzierżanowski0950c372019-04-02 19:29:506773 EXPECT_TRUE(response->did_use_http_auth);
[email protected]2df19bb2010-08-25 20:13:466774
6775 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:586776 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]2df19bb2010-08-25 20:13:466777}
6778
[email protected]23e482282013-06-14 16:08:026779void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086780 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426781 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086782 request.method = "GET";
bncce36dca22015-04-21 22:11:236783 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106784 request.traffic_annotation =
6785 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086786
[email protected]cb9bf6ca2011-01-28 13:15:276787 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496788 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6789 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096790 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276791
[email protected]c744cf22009-02-27 07:28:086792 // Since we have proxy, should try to establish tunnel.
6793 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176794 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6795 "Host: www.example.org:443\r\n"
6796 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086797 };
6798
6799 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236800 status, MockRead("Content-Length: 10\r\n\r\n"),
6801 // No response body because the test stops reading here.
6802 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086803 };
6804
Ryan Sleevib8d7ea02018-05-07 20:01:016805 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:076806 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086807
[email protected]49639fa2011-12-20 23:22:416808 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086809
bnc691fda62016-08-12 00:43:166810 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506811
tfarina42834112016-09-22 13:38:206812 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016813 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086814
6815 rv = callback.WaitForResult();
6816 EXPECT_EQ(expected_status, rv);
6817}
6818
[email protected]23e482282013-06-14 16:08:026819void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236820 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086821 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426822 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086823}
6824
bncd16676a2016-07-20 16:23:016825TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086826 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6827}
6828
bncd16676a2016-07-20 16:23:016829TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086830 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6831}
6832
bncd16676a2016-07-20 16:23:016833TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086834 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6835}
6836
bncd16676a2016-07-20 16:23:016837TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086838 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6839}
6840
bncd16676a2016-07-20 16:23:016841TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086842 ConnectStatusHelper(
6843 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6844}
6845
bncd16676a2016-07-20 16:23:016846TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086847 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6848}
6849
bncd16676a2016-07-20 16:23:016850TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086851 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6852}
6853
bncd16676a2016-07-20 16:23:016854TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086855 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6856}
6857
bncd16676a2016-07-20 16:23:016858TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086859 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6860}
6861
bncd16676a2016-07-20 16:23:016862TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086863 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6864}
6865
bncd16676a2016-07-20 16:23:016866TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086867 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6868}
6869
bncd16676a2016-07-20 16:23:016870TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086871 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6872}
6873
bncd16676a2016-07-20 16:23:016874TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086875 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6876}
6877
bncd16676a2016-07-20 16:23:016878TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086879 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6880}
6881
bncd16676a2016-07-20 16:23:016882TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086883 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6884}
6885
bncd16676a2016-07-20 16:23:016886TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086887 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6888}
6889
bncd16676a2016-07-20 16:23:016890TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376891 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6892}
6893
bncd16676a2016-07-20 16:23:016894TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086895 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6896}
6897
bncd16676a2016-07-20 16:23:016898TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086899 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6900}
6901
bncd16676a2016-07-20 16:23:016902TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086903 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6904}
6905
bncd16676a2016-07-20 16:23:016906TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086907 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6908}
6909
bncd16676a2016-07-20 16:23:016910TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086911 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6912}
6913
bncd16676a2016-07-20 16:23:016914TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086915 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6916}
6917
bncd16676a2016-07-20 16:23:016918TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086919 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6920}
6921
bncd16676a2016-07-20 16:23:016922TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086923 ConnectStatusHelperWithExpectedStatus(
6924 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546925 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086926}
6927
bncd16676a2016-07-20 16:23:016928TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086929 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6930}
6931
bncd16676a2016-07-20 16:23:016932TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086933 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6934}
6935
bncd16676a2016-07-20 16:23:016936TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086937 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6938}
6939
bncd16676a2016-07-20 16:23:016940TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086941 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6942}
6943
bncd16676a2016-07-20 16:23:016944TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086945 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6946}
6947
bncd16676a2016-07-20 16:23:016948TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086949 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6950}
6951
bncd16676a2016-07-20 16:23:016952TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086953 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6954}
6955
bncd16676a2016-07-20 16:23:016956TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086957 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6958}
6959
bncd16676a2016-07-20 16:23:016960TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086961 ConnectStatusHelper(
6962 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6963}
6964
bncd16676a2016-07-20 16:23:016965TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086966 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6967}
6968
bncd16676a2016-07-20 16:23:016969TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086970 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6971}
6972
bncd16676a2016-07-20 16:23:016973TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086974 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6975}
6976
bncd16676a2016-07-20 16:23:016977TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086978 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6979}
6980
bncd16676a2016-07-20 16:23:016981TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086982 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6983}
6984
bncd16676a2016-07-20 16:23:016985TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086986 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6987}
6988
bncd16676a2016-07-20 16:23:016989TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086990 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6991}
6992
[email protected]038e9a32008-10-08 22:40:166993// Test the flow when both the proxy server AND origin server require
6994// authentication. Again, this uses basic auth for both since that is
6995// the simplest to mock.
bncd16676a2016-07-20 16:23:016996TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276997 HttpRequestInfo request;
6998 request.method = "GET";
bncce36dca22015-04-21 22:11:236999 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107000 request.traffic_annotation =
7001 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277002
[email protected]038e9a32008-10-08 22:40:167003 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497004 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7005 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:097006 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:077007
bnc691fda62016-08-12 00:43:167008 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:167009
[email protected]f9ee6b52008-11-08 06:46:237010 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237011 MockWrite(
7012 "GET http://www.example.org/ HTTP/1.1\r\n"
7013 "Host: www.example.org\r\n"
7014 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237015 };
7016
[email protected]038e9a32008-10-08 22:40:167017 MockRead data_reads1[] = {
7018 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
7019 // Give a couple authenticate options (only the middle one is actually
7020 // supported).
[email protected]22927ad2009-09-21 19:56:197021 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:167022 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7023 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
7024 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7025 // Large content-length -- won't matter, as connection will be reset.
7026 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067027 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:167028 };
7029
bnc691fda62016-08-12 00:43:167030 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:167031 // request we should be issuing -- the final header line contains the
7032 // proxy's credentials.
7033 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237034 MockWrite(
7035 "GET http://www.example.org/ HTTP/1.1\r\n"
7036 "Host: www.example.org\r\n"
7037 "Proxy-Connection: keep-alive\r\n"
7038 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167039 };
7040
7041 // Now the proxy server lets the request pass through to origin server.
7042 // The origin server responds with a 401.
7043 MockRead data_reads2[] = {
7044 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7045 // Note: We are using the same realm-name as the proxy server. This is
7046 // completely valid, as realms are unique across hosts.
7047 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7048 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7049 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067050 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:167051 };
7052
bnc691fda62016-08-12 00:43:167053 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:167054 // the credentials for both the proxy and origin server.
7055 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237056 MockWrite(
7057 "GET http://www.example.org/ HTTP/1.1\r\n"
7058 "Host: www.example.org\r\n"
7059 "Proxy-Connection: keep-alive\r\n"
7060 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
7061 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167062 };
7063
7064 // Lastly we get the desired content.
7065 MockRead data_reads3[] = {
7066 MockRead("HTTP/1.0 200 OK\r\n"),
7067 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7068 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067069 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:167070 };
7071
Ryan Sleevib8d7ea02018-05-07 20:01:017072 StaticSocketDataProvider data1(data_reads1, data_writes1);
7073 StaticSocketDataProvider data2(data_reads2, data_writes2);
7074 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077075 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7076 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7077 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:167078
[email protected]49639fa2011-12-20 23:22:417079 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:167080
tfarina42834112016-09-22 13:38:207081 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017082 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167083
7084 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017085 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167086
bnc691fda62016-08-12 00:43:167087 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527088 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587089 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
[email protected]038e9a32008-10-08 22:40:167090
[email protected]49639fa2011-12-20 23:22:417091 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:167092
bnc691fda62016-08-12 00:43:167093 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:017094 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167095
7096 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017097 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167098
bnc691fda62016-08-12 00:43:167099 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527100 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587101 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]038e9a32008-10-08 22:40:167102
[email protected]49639fa2011-12-20 23:22:417103 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:167104
bnc691fda62016-08-12 00:43:167105 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7106 callback3.callback());
robpercival214763f2016-07-01 23:27:017107 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167108
7109 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017110 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167111
bnc691fda62016-08-12 00:43:167112 response = trans.GetResponseInfo();
Emily Starkf2c9bbd2019-04-09 17:08:587113 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]038e9a32008-10-08 22:40:167114 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:167115}
[email protected]4ddaf2502008-10-23 18:26:197116
[email protected]ea9dc9a2009-09-05 00:43:327117// For the NTLM implementation using SSPI, we skip the NTLM tests since we
7118// can't hook into its internals to cause it to generate predictable NTLM
7119// authorization headers.
7120#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377121// The NTLM authentication unit tests are based on known test data from the
7122// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
7123// flow rather than the implementation of the NTLM protocol. See net/ntlm
7124// for the implementation and testing of the protocol.
7125//
7126// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:297127
7128// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557129TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:427130 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:247131 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557132 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:107133 request.traffic_annotation =
7134 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547135
7136 // Ensure load is not disrupted by flags which suppress behaviour specific
7137 // to other auth schemes.
7138 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:247139
Zentaro Kavanagh6ccee512017-09-28 18:34:097140 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7141 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097142 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277143
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377144 // Generate the NTLM messages based on known test data.
7145 std::string negotiate_msg;
7146 std::string challenge_msg;
7147 std::string authenticate_msg;
7148 base::Base64Encode(
7149 base::StringPiece(
7150 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247151 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377152 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557153 base::Base64Encode(
7154 base::StringPiece(
7155 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247156 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557157 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377158 base::Base64Encode(
7159 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097160 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557161 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247162 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557163 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377164 &authenticate_msg);
7165
[email protected]3f918782009-02-28 01:29:247166 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557167 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7168 "Host: server\r\n"
7169 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247170 };
7171
7172 MockRead data_reads1[] = {
7173 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047174 // Negotiate and NTLM are often requested together. However, we only want
7175 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7176 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:247177 MockRead("WWW-Authenticate: NTLM\r\n"),
7178 MockRead("Connection: close\r\n"),
7179 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367180 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247181 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:247182 };
7183
7184 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167185 // After restarting with a null identity, this is the
7186 // request we should be issuing -- the final header line contains a Type
7187 // 1 message.
7188 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557189 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167190 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377191 "Authorization: NTLM "),
7192 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247193
bnc691fda62016-08-12 00:43:167194 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377195 // (using correct credentials). The second request continues on the
7196 // same connection.
bnc691fda62016-08-12 00:43:167197 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557198 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167199 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377200 "Authorization: NTLM "),
7201 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247202 };
7203
7204 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:027205 // The origin server responds with a Type 2 message.
7206 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377207 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7208 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027209 MockRead("Content-Type: text/html\r\n\r\n"),
7210 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:247211
Bence Béky1e4ef192017-09-18 19:58:027212 // Lastly we get the desired content.
7213 MockRead("HTTP/1.1 200 OK\r\n"),
7214 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7215 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:247216 };
7217
Ryan Sleevib8d7ea02018-05-07 20:01:017218 StaticSocketDataProvider data1(data_reads1, data_writes1);
7219 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077220 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7221 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:247222
Bence Béky83eb3512017-09-05 12:56:097223 SSLSocketDataProvider ssl1(ASYNC, OK);
7224 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7225 SSLSocketDataProvider ssl2(ASYNC, OK);
7226 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7227
[email protected]49639fa2011-12-20 23:22:417228 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:247229
bnc691fda62016-08-12 00:43:167230 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507231
tfarina42834112016-09-22 13:38:207232 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017233 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247234
7235 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017236 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247237
bnc691fda62016-08-12 00:43:167238 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227239
bnc691fda62016-08-12 00:43:167240 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527241 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587242 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
[email protected]3f918782009-02-28 01:29:247243
[email protected]49639fa2011-12-20 23:22:417244 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:257245
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377246 rv = trans.RestartWithAuth(
7247 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7248 callback2.callback());
robpercival214763f2016-07-01 23:27:017249 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257250
7251 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017252 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257253
bnc691fda62016-08-12 00:43:167254 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257255
bnc691fda62016-08-12 00:43:167256 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527257 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587258 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]10af5fe72011-01-31 16:17:257259
[email protected]49639fa2011-12-20 23:22:417260 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:247261
bnc691fda62016-08-12 00:43:167262 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017263 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247264
[email protected]0757e7702009-03-27 04:00:227265 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017266 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247267
bnc691fda62016-08-12 00:43:167268 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527269 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587270 EXPECT_FALSE(response->auth_challenge.has_value());
Bence Béky1e4ef192017-09-18 19:58:027271 EXPECT_EQ(14, response->headers->GetContentLength());
7272
7273 std::string response_data;
7274 rv = ReadTransaction(&trans, &response_data);
7275 EXPECT_THAT(rv, IsOk());
7276 EXPECT_EQ("Please Login\r\n", response_data);
7277
7278 EXPECT_TRUE(data1.AllReadDataConsumed());
7279 EXPECT_TRUE(data1.AllWriteDataConsumed());
7280 EXPECT_TRUE(data2.AllReadDataConsumed());
7281 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:247282}
7283
[email protected]385a4672009-03-11 22:21:297284// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557285TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:427286 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:297287 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557288 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:107289 request.traffic_annotation =
7290 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:297291
Zentaro Kavanagh6ccee512017-09-28 18:34:097292 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7293 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097294 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277295
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377296 // Generate the NTLM messages based on known test data.
7297 std::string negotiate_msg;
7298 std::string challenge_msg;
7299 std::string authenticate_msg;
7300 base::Base64Encode(
7301 base::StringPiece(
7302 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247303 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377304 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557305 base::Base64Encode(
7306 base::StringPiece(
7307 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247308 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557309 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377310 base::Base64Encode(
7311 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097312 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557313 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247314 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557315 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377316 &authenticate_msg);
7317
7318 // The authenticate message when |kWrongPassword| is sent.
7319 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557320 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
7321 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
7322 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
7323 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
7324 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
7325 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377326
Zentaro Kavanagh1890a3d2018-01-29 19:52:557327 // Sanity check that it's the same length as the correct authenticate message
7328 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377329 ASSERT_EQ(authenticate_msg.length(),
7330 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:557331 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377332
[email protected]385a4672009-03-11 22:21:297333 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557334 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7335 "Host: server\r\n"
7336 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297337 };
7338
7339 MockRead data_reads1[] = {
7340 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047341 // Negotiate and NTLM are often requested together. However, we only want
7342 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7343 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:297344 MockRead("WWW-Authenticate: NTLM\r\n"),
7345 MockRead("Connection: close\r\n"),
7346 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367347 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297348 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297349 };
7350
7351 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167352 // After restarting with a null identity, this is the
7353 // request we should be issuing -- the final header line contains a Type
7354 // 1 message.
7355 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557356 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167357 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377358 "Authorization: NTLM "),
7359 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297360
bnc691fda62016-08-12 00:43:167361 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377362 // (using incorrect credentials). The second request continues on the
7363 // same connection.
bnc691fda62016-08-12 00:43:167364 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557365 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167366 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377367 "Authorization: NTLM "),
7368 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297369 };
7370
7371 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377372 // The origin server responds with a Type 2 message.
7373 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7374 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7375 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
7376 MockRead("Content-Type: text/html\r\n\r\n"),
7377 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297378
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377379 // Wrong password.
7380 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7381 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
7382 MockRead("Content-Length: 42\r\n"),
7383 MockRead("Content-Type: text/html\r\n\r\n"),
7384 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297385 };
7386
7387 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:167388 // After restarting with a null identity, this is the
7389 // request we should be issuing -- the final header line contains a Type
7390 // 1 message.
7391 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557392 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167393 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377394 "Authorization: NTLM "),
7395 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297396
bnc691fda62016-08-12 00:43:167397 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7398 // (the credentials for the origin server). The second request continues
7399 // on the same connection.
7400 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557401 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167402 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377403 "Authorization: NTLM "),
7404 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297405 };
7406
7407 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:027408 // The origin server responds with a Type 2 message.
7409 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377410 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7411 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027412 MockRead("Content-Type: text/html\r\n\r\n"),
7413 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297414
Bence Béky1e4ef192017-09-18 19:58:027415 // Lastly we get the desired content.
7416 MockRead("HTTP/1.1 200 OK\r\n"),
7417 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7418 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:297419 };
7420
Ryan Sleevib8d7ea02018-05-07 20:01:017421 StaticSocketDataProvider data1(data_reads1, data_writes1);
7422 StaticSocketDataProvider data2(data_reads2, data_writes2);
7423 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077424 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7425 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7426 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:297427
Bence Béky83eb3512017-09-05 12:56:097428 SSLSocketDataProvider ssl1(ASYNC, OK);
7429 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7430 SSLSocketDataProvider ssl2(ASYNC, OK);
7431 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7432 SSLSocketDataProvider ssl3(ASYNC, OK);
7433 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
7434
[email protected]49639fa2011-12-20 23:22:417435 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:297436
bnc691fda62016-08-12 00:43:167437 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507438
tfarina42834112016-09-22 13:38:207439 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017440 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297441
7442 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017443 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297444
bnc691fda62016-08-12 00:43:167445 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:297446
bnc691fda62016-08-12 00:43:167447 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527448 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587449 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
[email protected]385a4672009-03-11 22:21:297450
[email protected]49639fa2011-12-20 23:22:417451 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:297452
[email protected]0757e7702009-03-27 04:00:227453 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377454 rv = trans.RestartWithAuth(
7455 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
7456 callback2.callback());
robpercival214763f2016-07-01 23:27:017457 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297458
[email protected]10af5fe72011-01-31 16:17:257459 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017460 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297461
bnc691fda62016-08-12 00:43:167462 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417463 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167464 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017465 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257466 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017467 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167468 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227469
bnc691fda62016-08-12 00:43:167470 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527471 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587472 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
[email protected]0757e7702009-03-27 04:00:227473
[email protected]49639fa2011-12-20 23:22:417474 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:227475
7476 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377477 rv = trans.RestartWithAuth(
7478 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7479 callback4.callback());
robpercival214763f2016-07-01 23:27:017480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257481
7482 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:017483 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257484
bnc691fda62016-08-12 00:43:167485 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257486
[email protected]49639fa2011-12-20 23:22:417487 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:257488
7489 // One more roundtrip
bnc691fda62016-08-12 00:43:167490 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:017491 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227492
7493 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:017494 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:227495
bnc691fda62016-08-12 00:43:167496 response = trans.GetResponseInfo();
Emily Starkf2c9bbd2019-04-09 17:08:587497 EXPECT_FALSE(response->auth_challenge.has_value());
Bence Béky1e4ef192017-09-18 19:58:027498 EXPECT_EQ(14, response->headers->GetContentLength());
7499
7500 std::string response_data;
7501 rv = ReadTransaction(&trans, &response_data);
7502 EXPECT_THAT(rv, IsOk());
7503 EXPECT_EQ("Please Login\r\n", response_data);
7504
7505 EXPECT_TRUE(data1.AllReadDataConsumed());
7506 EXPECT_TRUE(data1.AllWriteDataConsumed());
7507 EXPECT_TRUE(data2.AllReadDataConsumed());
7508 EXPECT_TRUE(data2.AllWriteDataConsumed());
7509 EXPECT_TRUE(data3.AllReadDataConsumed());
7510 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:297511}
Bence Béky83eb3512017-09-05 12:56:097512
Bence Béky3238f2e12017-09-22 22:44:497513// Server requests NTLM authentication, which is not supported over HTTP/2.
7514// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:097515TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:097516 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7517 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:097518
Zentaro Kavanagh1890a3d2018-01-29 19:52:557519 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:097520
7521 HttpRequestInfo request;
7522 request.method = "GET";
7523 request.url = GURL(kUrl);
Ramin Halavatib5e433e62018-02-07 07:41:107524 request.traffic_annotation =
7525 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:097526
7527 // First request without credentials.
Ryan Hamilton0239aac2018-05-19 00:03:137528 spdy::SpdyHeaderBlock request_headers0(
7529 spdy_util_.ConstructGetHeaderBlock(kUrl));
7530 spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
Bence Béky83eb3512017-09-05 12:56:097531 1, std::move(request_headers0), LOWEST, true));
7532
Ryan Hamilton0239aac2018-05-19 00:03:137533 spdy::SpdyHeaderBlock response_headers0;
7534 response_headers0[spdy::kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:097535 response_headers0["www-authenticate"] = "NTLM";
Ryan Hamilton0239aac2018-05-19 00:03:137536 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Béky83eb3512017-09-05 12:56:097537 1, std::move(response_headers0), true));
7538
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377539 // Stream 1 is closed.
7540 spdy_util_.UpdateWithStreamDestruction(1);
7541
7542 // Generate the NTLM messages based on known test data.
7543 std::string negotiate_msg;
7544 std::string challenge_msg;
7545 std::string authenticate_msg;
7546 base::Base64Encode(
7547 base::StringPiece(
7548 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247549 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377550 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557551 base::Base64Encode(
7552 base::StringPiece(
7553 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247554 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557555 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377556 base::Base64Encode(
7557 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097558 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557559 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247560 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557561 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377562 &authenticate_msg);
7563
7564 // Retry with authorization header.
Ryan Hamilton0239aac2018-05-19 00:03:137565 spdy::SpdyHeaderBlock request_headers1(
7566 spdy_util_.ConstructGetHeaderBlock(kUrl));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377567 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
Ryan Hamilton0239aac2018-05-19 00:03:137568 spdy::SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377569 3, std::move(request_headers1), LOWEST, true));
7570
Ryan Hamilton0239aac2018-05-19 00:03:137571 spdy::SpdySerializedFrame rst(
7572 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377573
Bence Béky3238f2e12017-09-22 22:44:497574 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
7575 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:097576
7577 // Retry yet again using HTTP/1.1.
7578 MockWrite writes1[] = {
7579 // After restarting with a null identity, this is the
7580 // request we should be issuing -- the final header line contains a Type
7581 // 1 message.
7582 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557583 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097584 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377585 "Authorization: NTLM "),
7586 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097587
7588 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7589 // (the credentials for the origin server). The second request continues
7590 // on the same connection.
7591 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557592 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097593 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377594 "Authorization: NTLM "),
7595 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097596 };
7597
7598 MockRead reads1[] = {
7599 // The origin server responds with a Type 2 message.
7600 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377601 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7602 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:097603 MockRead("Content-Type: text/html\r\n\r\n"),
7604 MockRead("You are not authorized to view this page\r\n"),
7605
7606 // Lastly we get the desired content.
7607 MockRead("HTTP/1.1 200 OK\r\n"),
7608 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027609 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:097610 };
Ryan Sleevib8d7ea02018-05-07 20:01:017611 SequencedSocketData data0(reads0, writes0);
7612 StaticSocketDataProvider data1(reads1, writes1);
Bence Béky83eb3512017-09-05 12:56:097613 session_deps_.socket_factory->AddSocketDataProvider(&data0);
7614 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7615
7616 SSLSocketDataProvider ssl0(ASYNC, OK);
7617 ssl0.next_proto = kProtoHTTP2;
7618 SSLSocketDataProvider ssl1(ASYNC, OK);
7619 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
7620 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7621
7622 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7623 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7624
7625 TestCompletionCallback callback1;
7626 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
7627 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7628
7629 rv = callback1.WaitForResult();
7630 EXPECT_THAT(rv, IsOk());
7631
7632 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7633
7634 const HttpResponseInfo* response = trans.GetResponseInfo();
7635 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587636 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
Bence Béky83eb3512017-09-05 12:56:097637
7638 TestCompletionCallback callback2;
7639
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377640 rv = trans.RestartWithAuth(
7641 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7642 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:097643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7644
7645 rv = callback2.WaitForResult();
7646 EXPECT_THAT(rv, IsOk());
7647
7648 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7649
7650 response = trans.GetResponseInfo();
7651 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587652 EXPECT_FALSE(response->auth_challenge.has_value());
Bence Béky83eb3512017-09-05 12:56:097653
7654 TestCompletionCallback callback3;
7655
7656 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
7657 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7658
7659 rv = callback3.WaitForResult();
7660 EXPECT_THAT(rv, IsOk());
7661
7662 response = trans.GetResponseInfo();
7663 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587664 EXPECT_FALSE(response->auth_challenge.has_value());
Bence Béky1e4ef192017-09-18 19:58:027665 EXPECT_EQ(14, response->headers->GetContentLength());
7666
7667 std::string response_data;
7668 rv = ReadTransaction(&trans, &response_data);
7669 EXPECT_THAT(rv, IsOk());
7670 EXPECT_EQ("Please Login\r\n", response_data);
7671
7672 EXPECT_TRUE(data0.AllReadDataConsumed());
7673 EXPECT_TRUE(data0.AllWriteDataConsumed());
7674 EXPECT_TRUE(data1.AllReadDataConsumed());
7675 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:097676}
David Benjamin5cb91132018-04-06 05:54:497677
7678// Test that, if we have an NTLM proxy and the origin resets the connection, we
7679// do no retry forever checking for TLS version interference. This is a
7680// regression test for https://crbug.com/823387.
7681TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
7682 // The NTLM test data expects the proxy to be named 'server'. The origin is
7683 // https://origin/.
7684 session_deps_.proxy_resolution_service =
7685 ProxyResolutionService::CreateFixedFromPacResult(
7686 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
7687
7688 SSLConfig config;
David Benjamin5cb91132018-04-06 05:54:497689 session_deps_.ssl_config_service =
Ryan Sleevib8449e02018-07-15 04:31:077690 std::make_unique<TestSSLConfigService>(config);
David Benjamin5cb91132018-04-06 05:54:497691
7692 HttpRequestInfo request;
7693 request.method = "GET";
7694 request.url = GURL("https://origin/");
7695 request.traffic_annotation =
7696 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7697
7698 // Ensure load is not disrupted by flags which suppress behaviour specific
7699 // to other auth schemes.
7700 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7701
7702 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7703 MockGetMSTime, MockGenerateRandom, MockGetHostName);
7704 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7705
7706 // Generate the NTLM messages based on known test data.
7707 std::string negotiate_msg;
7708 std::string challenge_msg;
7709 std::string authenticate_msg;
7710 base::Base64Encode(
7711 base::StringPiece(
7712 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247713 base::size(ntlm::test::kExpectedNegotiateMsg)),
David Benjamin5cb91132018-04-06 05:54:497714 &negotiate_msg);
7715 base::Base64Encode(
7716 base::StringPiece(
7717 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247718 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
David Benjamin5cb91132018-04-06 05:54:497719 &challenge_msg);
7720 base::Base64Encode(
7721 base::StringPiece(
7722 reinterpret_cast<const char*>(
7723 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247724 base::size(
David Benjamin5cb91132018-04-06 05:54:497725 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
7726 &authenticate_msg);
7727
7728 MockWrite data_writes[] = {
7729 // The initial CONNECT request.
7730 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7731 "Host: origin:443\r\n"
7732 "Proxy-Connection: keep-alive\r\n\r\n"),
7733
7734 // After restarting with an identity.
7735 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7736 "Host: origin:443\r\n"
7737 "Proxy-Connection: keep-alive\r\n"
7738 "Proxy-Authorization: NTLM "),
7739 MockWrite(negotiate_msg.c_str()),
7740 // End headers.
7741 MockWrite("\r\n\r\n"),
7742
7743 // The second restart.
7744 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7745 "Host: origin:443\r\n"
7746 "Proxy-Connection: keep-alive\r\n"
7747 "Proxy-Authorization: NTLM "),
7748 MockWrite(authenticate_msg.c_str()),
7749 // End headers.
7750 MockWrite("\r\n\r\n"),
7751 };
7752
7753 MockRead data_reads[] = {
7754 // The initial NTLM response.
7755 MockRead("HTTP/1.1 407 Access Denied\r\n"
7756 "Content-Length: 0\r\n"
7757 "Proxy-Authenticate: NTLM\r\n\r\n"),
7758
7759 // The NTLM challenge message.
7760 MockRead("HTTP/1.1 407 Access Denied\r\n"
7761 "Content-Length: 0\r\n"
7762 "Proxy-Authenticate: NTLM "),
7763 MockRead(challenge_msg.c_str()),
7764 // End headers.
7765 MockRead("\r\n\r\n"),
7766
7767 // Finally the tunnel is established.
7768 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
7769 };
7770
Ryan Sleevib8d7ea02018-05-07 20:01:017771 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497772 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
Ryan Sleevib8d7ea02018-05-07 20:01:017773 StaticSocketDataProvider data2(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497774 SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
Steven Valdez0ef94d02018-11-19 23:28:137775 data_ssl2.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
David Benjamin5cb91132018-04-06 05:54:497776 session_deps_.socket_factory->AddSocketDataProvider(&data);
7777 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
7778 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7779 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
7780
7781 // Start the transaction. The proxy responds with an NTLM authentication
7782 // request.
7783 TestCompletionCallback callback;
7784 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7785 int rv = callback.GetResult(
7786 trans.Start(&request, callback.callback(), NetLogWithSource()));
7787
7788 EXPECT_THAT(rv, IsOk());
7789 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7790 const HttpResponseInfo* response = trans.GetResponseInfo();
7791 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587792 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge));
David Benjamin5cb91132018-04-06 05:54:497793
7794 // Configure credentials. The proxy responds with the challenge message.
7795 rv = callback.GetResult(trans.RestartWithAuth(
7796 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7797 callback.callback()));
7798 EXPECT_THAT(rv, IsOk());
7799 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7800 response = trans.GetResponseInfo();
7801 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587802 EXPECT_FALSE(response->auth_challenge.has_value());
David Benjamin5cb91132018-04-06 05:54:497803
7804 // Restart once more. The tunnel will be established and the the SSL handshake
7805 // will reset. The TLS 1.3 version interference probe will then kick in and
7806 // restart the process. The proxy responds with another NTLM authentiation
7807 // request, but we don't need to provide credentials as the cached ones work/
7808 rv = callback.GetResult(
7809 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7810 EXPECT_THAT(rv, IsOk());
7811 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7812 response = trans.GetResponseInfo();
7813 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587814 EXPECT_FALSE(response->auth_challenge.has_value());
David Benjamin5cb91132018-04-06 05:54:497815
7816 // The proxy responds with the NTLM challenge message.
7817 rv = callback.GetResult(
7818 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7819 EXPECT_THAT(rv, IsOk());
7820 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7821 response = trans.GetResponseInfo();
7822 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587823 EXPECT_FALSE(response->auth_challenge.has_value());
David Benjamin5cb91132018-04-06 05:54:497824
7825 // Send the NTLM authenticate message. The tunnel is established and the
7826 // handshake resets again. We should not retry again.
7827 rv = callback.GetResult(
7828 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7829 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
7830}
7831
[email protected]ea9dc9a2009-09-05 00:43:327832#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:297833
[email protected]4ddaf2502008-10-23 18:26:197834// Test reading a server response which has only headers, and no body.
7835// After some maximum number of bytes is consumed, the transaction should
7836// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:017837TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:427838 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:197839 request.method = "GET";
bncce36dca22015-04-21 22:11:237840 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107841 request.traffic_annotation =
7842 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:197843
danakj1fd259a02016-04-16 03:17:097844 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167845 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277846
[email protected]b75b7b2f2009-10-06 00:54:537847 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:437848 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:537849 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:197850
7851 MockRead data_reads[] = {
7852 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:067853 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:197854 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:067855 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:197856 };
Ryan Sleevib8d7ea02018-05-07 20:01:017857 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077858 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:197859
[email protected]49639fa2011-12-20 23:22:417860 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:197861
tfarina42834112016-09-22 13:38:207862 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:197864
7865 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017866 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197867}
[email protected]f4e426b2008-11-05 00:24:497868
7869// Make sure that we don't try to reuse a TCPClientSocket when failing to
7870// establish tunnel.
7871// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017872TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277873 HttpRequestInfo request;
7874 request.method = "GET";
bncce36dca22015-04-21 22:11:237875 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107876 request.traffic_annotation =
7877 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277878
[email protected]f4e426b2008-11-05 00:24:497879 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497880 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7881 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017882
danakj1fd259a02016-04-16 03:17:097883 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497884
bnc87dcefc2017-05-25 12:47:587885 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197886 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497887
[email protected]f4e426b2008-11-05 00:24:497888 // Since we have proxy, should try to establish tunnel.
7889 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177890 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7891 "Host: www.example.org:443\r\n"
7892 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497893 };
7894
[email protected]77848d12008-11-14 00:00:227895 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497896 // connection. Usually a proxy would return 501 (not implemented),
7897 // or 200 (tunnel established).
7898 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237899 MockRead("HTTP/1.1 404 Not Found\r\n"),
7900 MockRead("Content-Length: 10\r\n\r\n"),
7901 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497902 };
7903
Ryan Sleevib8d7ea02018-05-07 20:01:017904 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:077905 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497906
[email protected]49639fa2011-12-20 23:22:417907 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497908
tfarina42834112016-09-22 13:38:207909 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017910 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497911
7912 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017913 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497914
[email protected]b4404c02009-04-10 16:38:527915 // Empty the current queue. This is necessary because idle sockets are
7916 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557917 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527918
[email protected]f4e426b2008-11-05 00:24:497919 // We now check to make sure the TCPClientSocket was not added back to
7920 // the pool.
[email protected]90499482013-06-01 00:39:507921 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497922 trans.reset();
fdoray92e35a72016-06-10 15:54:557923 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497924 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507925 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497926}
[email protected]372d34a2008-11-05 21:30:517927
[email protected]1b157c02009-04-21 01:55:407928// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017929TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427930 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407931 request.method = "GET";
bncce36dca22015-04-21 22:11:237932 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107933 request.traffic_annotation =
7934 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407935
danakj1fd259a02016-04-16 03:17:097936 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277937
bnc691fda62016-08-12 00:43:167938 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277939
[email protected]1b157c02009-04-21 01:55:407940 MockRead data_reads[] = {
7941 // A part of the response body is received with the response headers.
7942 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7943 // The rest of the response body is received in two parts.
7944 MockRead("lo"),
7945 MockRead(" world"),
7946 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067947 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407948 };
7949
Ryan Sleevib8d7ea02018-05-07 20:01:017950 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077951 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407952
[email protected]49639fa2011-12-20 23:22:417953 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407954
tfarina42834112016-09-22 13:38:207955 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017956 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407957
7958 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017959 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407960
bnc691fda62016-08-12 00:43:167961 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527962 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407963
wezca1070932016-05-26 20:30:527964 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407965 std::string status_line = response->headers->GetStatusLine();
7966 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7967
[email protected]90499482013-06-01 00:39:507968 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407969
7970 std::string response_data;
bnc691fda62016-08-12 00:43:167971 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017972 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407973 EXPECT_EQ("hello world", response_data);
7974
7975 // Empty the current queue. This is necessary because idle sockets are
7976 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557977 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407978
7979 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507980 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407981}
7982
[email protected]76a505b2010-08-25 06:23:007983// Make sure that we recycle a SSL socket after reading all of the response
7984// body.
bncd16676a2016-07-20 16:23:017985TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007986 HttpRequestInfo request;
7987 request.method = "GET";
bncce36dca22015-04-21 22:11:237988 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107989 request.traffic_annotation =
7990 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007991
7992 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237993 MockWrite(
7994 "GET / HTTP/1.1\r\n"
7995 "Host: www.example.org\r\n"
7996 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007997 };
7998
7999 MockRead data_reads[] = {
8000 MockRead("HTTP/1.1 200 OK\r\n"),
8001 MockRead("Content-Length: 11\r\n\r\n"),
8002 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068003 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:008004 };
8005
[email protected]8ddf8322012-02-23 18:08:068006 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078007 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:008008
Ryan Sleevib8d7ea02018-05-07 20:01:018009 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078010 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:008011
[email protected]49639fa2011-12-20 23:22:418012 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008013
danakj1fd259a02016-04-16 03:17:098014 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168015 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008016
tfarina42834112016-09-22 13:38:208017 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008018
robpercival214763f2016-07-01 23:27:018019 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8020 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008021
bnc691fda62016-08-12 00:43:168022 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528023 ASSERT_TRUE(response);
8024 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008025 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8026
[email protected]90499482013-06-01 00:39:508027 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008028
8029 std::string response_data;
bnc691fda62016-08-12 00:43:168030 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018031 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008032 EXPECT_EQ("hello world", response_data);
8033
8034 // Empty the current queue. This is necessary because idle sockets are
8035 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558036 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008037
8038 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238039 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008040}
8041
8042// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
8043// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:018044TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:008045 HttpRequestInfo request;
8046 request.method = "GET";
bncce36dca22015-04-21 22:11:238047 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108048 request.traffic_annotation =
8049 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:008050
8051 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238052 MockWrite(
8053 "GET / HTTP/1.1\r\n"
8054 "Host: www.example.org\r\n"
8055 "Connection: keep-alive\r\n\r\n"),
8056 MockWrite(
8057 "GET / HTTP/1.1\r\n"
8058 "Host: www.example.org\r\n"
8059 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:008060 };
8061
8062 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:428063 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8064 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:008065
[email protected]8ddf8322012-02-23 18:08:068066 SSLSocketDataProvider ssl(ASYNC, OK);
8067 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078068 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8069 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:008070
Ryan Sleevib8d7ea02018-05-07 20:01:018071 StaticSocketDataProvider data(data_reads, data_writes);
8072 StaticSocketDataProvider data2(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078073 session_deps_.socket_factory->AddSocketDataProvider(&data);
8074 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:008075
[email protected]49639fa2011-12-20 23:22:418076 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008077
danakj1fd259a02016-04-16 03:17:098078 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:588079 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198080 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008081
tfarina42834112016-09-22 13:38:208082 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008083
robpercival214763f2016-07-01 23:27:018084 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8085 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008086
8087 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528088 ASSERT_TRUE(response);
8089 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008090 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8091
[email protected]90499482013-06-01 00:39:508092 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008093
8094 std::string response_data;
8095 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018096 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008097 EXPECT_EQ("hello world", response_data);
8098
8099 // Empty the current queue. This is necessary because idle sockets are
8100 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558101 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008102
8103 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238104 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008105
8106 // Now start the second transaction, which should reuse the previous socket.
8107
bnc87dcefc2017-05-25 12:47:588108 trans =
Jeremy Roman0579ed62017-08-29 15:56:198109 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008110
tfarina42834112016-09-22 13:38:208111 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008112
robpercival214763f2016-07-01 23:27:018113 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8114 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008115
8116 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528117 ASSERT_TRUE(response);
8118 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008119 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8120
[email protected]90499482013-06-01 00:39:508121 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008122
8123 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018124 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008125 EXPECT_EQ("hello world", response_data);
8126
8127 // Empty the current queue. This is necessary because idle sockets are
8128 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558129 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008130
8131 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238132 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008133}
8134
maksim.sisov0adf8592016-07-15 06:25:568135// Grab a socket, use it, and put it back into the pool. Then, make
8136// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018137TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568138 HttpRequestInfo request;
8139 request.method = "GET";
8140 request.url = GURL("http://www.example.org/");
8141 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108142 request.traffic_annotation =
8143 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568144
8145 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8146
bnc691fda62016-08-12 00:43:168147 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568148
8149 MockRead data_reads[] = {
8150 // A part of the response body is received with the response headers.
8151 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8152 // The rest of the response body is received in two parts.
8153 MockRead("lo"), MockRead(" world"),
8154 MockRead("junk"), // Should not be read!!
8155 MockRead(SYNCHRONOUS, OK),
8156 };
8157
Ryan Sleevib8d7ea02018-05-07 20:01:018158 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
maksim.sisov0adf8592016-07-15 06:25:568159 session_deps_.socket_factory->AddSocketDataProvider(&data);
8160
8161 TestCompletionCallback callback;
8162
tfarina42834112016-09-22 13:38:208163 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568164 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8165
8166 EXPECT_THAT(callback.GetResult(rv), IsOk());
8167
bnc691fda62016-08-12 00:43:168168 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568169 ASSERT_TRUE(response);
8170 EXPECT_TRUE(response->headers);
8171 std::string status_line = response->headers->GetStatusLine();
8172 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8173
8174 // Make memory critical notification and ensure the transaction still has been
8175 // operating right.
8176 base::MemoryPressureListener::NotifyMemoryPressure(
8177 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8178 base::RunLoop().RunUntilIdle();
8179
8180 // Socket should not be flushed as long as it is not idle.
8181 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8182
8183 std::string response_data;
bnc691fda62016-08-12 00:43:168184 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568185 EXPECT_THAT(rv, IsOk());
8186 EXPECT_EQ("hello world", response_data);
8187
8188 // Empty the current queue. This is necessary because idle sockets are
8189 // added to the connection pool asynchronously with a PostTask.
8190 base::RunLoop().RunUntilIdle();
8191
8192 // We now check to make sure the socket was added back to the pool.
8193 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8194
8195 // Idle sockets should be flushed now.
8196 base::MemoryPressureListener::NotifyMemoryPressure(
8197 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8198 base::RunLoop().RunUntilIdle();
8199
8200 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8201}
8202
yucliu48f235d2018-01-11 00:59:558203// Disable idle socket closing on memory pressure.
8204// Grab a socket, use it, and put it back into the pool. Then, make
8205// low memory notification and ensure the socket pool is NOT flushed.
8206TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
8207 HttpRequestInfo request;
8208 request.method = "GET";
8209 request.url = GURL("http://www.example.org/");
8210 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108211 request.traffic_annotation =
8212 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:558213
8214 // Disable idle socket closing on memory pressure.
8215 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
8216 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8217
8218 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8219
8220 MockRead data_reads[] = {
8221 // A part of the response body is received with the response headers.
8222 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8223 // The rest of the response body is received in two parts.
8224 MockRead("lo"), MockRead(" world"),
8225 MockRead("junk"), // Should not be read!!
8226 MockRead(SYNCHRONOUS, OK),
8227 };
8228
Ryan Sleevib8d7ea02018-05-07 20:01:018229 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
yucliu48f235d2018-01-11 00:59:558230 session_deps_.socket_factory->AddSocketDataProvider(&data);
8231
8232 TestCompletionCallback callback;
8233
8234 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
8235 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8236
8237 EXPECT_THAT(callback.GetResult(rv), IsOk());
8238
8239 const HttpResponseInfo* response = trans.GetResponseInfo();
8240 ASSERT_TRUE(response);
8241 EXPECT_TRUE(response->headers);
8242 std::string status_line = response->headers->GetStatusLine();
8243 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8244
8245 // Make memory critical notification and ensure the transaction still has been
8246 // operating right.
8247 base::MemoryPressureListener::NotifyMemoryPressure(
8248 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8249 base::RunLoop().RunUntilIdle();
8250
8251 // Socket should not be flushed as long as it is not idle.
8252 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8253
8254 std::string response_data;
8255 rv = ReadTransaction(&trans, &response_data);
8256 EXPECT_THAT(rv, IsOk());
8257 EXPECT_EQ("hello world", response_data);
8258
8259 // Empty the current queue. This is necessary because idle sockets are
8260 // added to the connection pool asynchronously with a PostTask.
8261 base::RunLoop().RunUntilIdle();
8262
8263 // We now check to make sure the socket was added back to the pool.
8264 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8265
8266 // Idle sockets should NOT be flushed on moderate memory pressure.
8267 base::MemoryPressureListener::NotifyMemoryPressure(
8268 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
8269 base::RunLoop().RunUntilIdle();
8270
8271 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8272
8273 // Idle sockets should NOT be flushed on critical memory pressure.
8274 base::MemoryPressureListener::NotifyMemoryPressure(
8275 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8276 base::RunLoop().RunUntilIdle();
8277
8278 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8279}
8280
maksim.sisov0adf8592016-07-15 06:25:568281// Grab an SSL socket, use it, and put it back into the pool. Then, make
8282// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018283TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568284 HttpRequestInfo request;
8285 request.method = "GET";
8286 request.url = GURL("https://www.example.org/");
8287 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108288 request.traffic_annotation =
8289 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568290
8291 MockWrite data_writes[] = {
8292 MockWrite("GET / HTTP/1.1\r\n"
8293 "Host: www.example.org\r\n"
8294 "Connection: keep-alive\r\n\r\n"),
8295 };
8296
8297 MockRead data_reads[] = {
8298 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8299 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
8300
8301 SSLSocketDataProvider ssl(ASYNC, OK);
8302 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8303
Ryan Sleevib8d7ea02018-05-07 20:01:018304 StaticSocketDataProvider data(data_reads, data_writes);
maksim.sisov0adf8592016-07-15 06:25:568305 session_deps_.socket_factory->AddSocketDataProvider(&data);
8306
8307 TestCompletionCallback callback;
8308
8309 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168310 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568311
Matt Menke9d5e2c92019-02-05 01:42:238312 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
tfarina42834112016-09-22 13:38:208313 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568314
8315 EXPECT_THAT(callback.GetResult(rv), IsOk());
8316
bnc691fda62016-08-12 00:43:168317 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568318 ASSERT_TRUE(response);
8319 ASSERT_TRUE(response->headers);
8320 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8321
8322 // Make memory critical notification and ensure the transaction still has been
8323 // operating right.
8324 base::MemoryPressureListener::NotifyMemoryPressure(
8325 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8326 base::RunLoop().RunUntilIdle();
8327
Matt Menke9d5e2c92019-02-05 01:42:238328 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568329
8330 std::string response_data;
bnc691fda62016-08-12 00:43:168331 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568332 EXPECT_THAT(rv, IsOk());
8333 EXPECT_EQ("hello world", response_data);
8334
8335 // Empty the current queue. This is necessary because idle sockets are
8336 // added to the connection pool asynchronously with a PostTask.
8337 base::RunLoop().RunUntilIdle();
8338
8339 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238340 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568341
8342 // Make memory notification once again and ensure idle socket is closed.
8343 base::MemoryPressureListener::NotifyMemoryPressure(
8344 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8345 base::RunLoop().RunUntilIdle();
8346
Matt Menke9d5e2c92019-02-05 01:42:238347 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568348}
8349
[email protected]b4404c02009-04-10 16:38:528350// Make sure that we recycle a socket after a zero-length response.
8351// http://crbug.com/9880
bncd16676a2016-07-20 16:23:018352TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:428353 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:528354 request.method = "GET";
bncce36dca22015-04-21 22:11:238355 request.url = GURL(
8356 "http://www.example.org/csi?v=3&s=web&action=&"
8357 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
8358 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
8359 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e62018-02-07 07:41:108360 request.traffic_annotation =
8361 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:528362
danakj1fd259a02016-04-16 03:17:098363 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278364
[email protected]b4404c02009-04-10 16:38:528365 MockRead data_reads[] = {
8366 MockRead("HTTP/1.1 204 No Content\r\n"
8367 "Content-Length: 0\r\n"
8368 "Content-Type: text/html\r\n\r\n"),
8369 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:068370 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:528371 };
8372
Ryan Sleevib8d7ea02018-05-07 20:01:018373 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:078374 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:528375
mmenkecc2298e2015-12-07 18:20:188376 // Transaction must be created after the MockReads, so it's destroyed before
8377 // them.
bnc691fda62016-08-12 00:43:168378 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:188379
[email protected]49639fa2011-12-20 23:22:418380 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:528381
tfarina42834112016-09-22 13:38:208382 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018383 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:528384
8385 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018386 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528387
bnc691fda62016-08-12 00:43:168388 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528389 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:528390
wezca1070932016-05-26 20:30:528391 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:528392 std::string status_line = response->headers->GetStatusLine();
8393 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
8394
[email protected]90499482013-06-01 00:39:508395 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528396
8397 std::string response_data;
bnc691fda62016-08-12 00:43:168398 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018399 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528400 EXPECT_EQ("", response_data);
8401
8402 // Empty the current queue. This is necessary because idle sockets are
8403 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558404 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:528405
8406 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508407 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528408}
8409
bncd16676a2016-07-20 16:23:018410TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:098411 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:228412 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:198413 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:228414 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:278415
[email protected]1c773ea12009-04-28 19:58:428416 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:518417 // Transaction 1: a GET request that succeeds. The socket is recycled
8418 // after use.
8419 request[0].method = "GET";
8420 request[0].url = GURL("http://www.google.com/");
8421 request[0].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108422 request[0].traffic_annotation =
8423 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518424 // Transaction 2: a POST request. Reuses the socket kept alive from
8425 // transaction 1. The first attempts fails when writing the POST data.
8426 // This causes the transaction to retry with a new socket. The second
8427 // attempt succeeds.
8428 request[1].method = "POST";
8429 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:278430 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:518431 request[1].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108432 request[1].traffic_annotation =
8433 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518434
danakj1fd259a02016-04-16 03:17:098435 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:518436
8437 // The first socket is used for transaction 1 and the first attempt of
8438 // transaction 2.
8439
8440 // The response of transaction 1.
8441 MockRead data_reads1[] = {
8442 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
8443 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068444 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518445 };
8446 // The mock write results of transaction 1 and the first attempt of
8447 // transaction 2.
8448 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:068449 MockWrite(SYNCHRONOUS, 64), // GET
8450 MockWrite(SYNCHRONOUS, 93), // POST
8451 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:518452 };
Ryan Sleevib8d7ea02018-05-07 20:01:018453 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:518454
8455 // The second socket is used for the second attempt of transaction 2.
8456
8457 // The response of transaction 2.
8458 MockRead data_reads2[] = {
8459 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
8460 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:068461 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518462 };
8463 // The mock write results of the second attempt of transaction 2.
8464 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:068465 MockWrite(SYNCHRONOUS, 93), // POST
8466 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:518467 };
Ryan Sleevib8d7ea02018-05-07 20:01:018468 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:518469
[email protected]bb88e1d32013-05-03 23:11:078470 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8471 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:518472
thestig9d3bb0c2015-01-24 00:49:518473 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:518474 "hello world", "welcome"
8475 };
8476
8477 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:168478 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:518479
[email protected]49639fa2011-12-20 23:22:418480 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:518481
tfarina42834112016-09-22 13:38:208482 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018483 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:518484
8485 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018486 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518487
bnc691fda62016-08-12 00:43:168488 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528489 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:518490
wezca1070932016-05-26 20:30:528491 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:518492 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8493
8494 std::string response_data;
bnc691fda62016-08-12 00:43:168495 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018496 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518497 EXPECT_EQ(kExpectedResponseData[i], response_data);
8498 }
8499}
[email protected]f9ee6b52008-11-08 06:46:238500
8501// Test the request-challenge-retry sequence for basic auth when there is
8502// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:168503// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:018504TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:428505 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238506 request.method = "GET";
bncce36dca22015-04-21 22:11:238507 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:418508 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:108509 request.traffic_annotation =
8510 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:298511
danakj1fd259a02016-04-16 03:17:098512 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168513 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278514
[email protected]a97cca42009-08-14 01:00:298515 // The password contains an escaped character -- for this test to pass it
8516 // will need to be unescaped by HttpNetworkTransaction.
8517 EXPECT_EQ("b%40r", request.url.password());
8518
[email protected]f9ee6b52008-11-08 06:46:238519 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238520 MockWrite(
8521 "GET / HTTP/1.1\r\n"
8522 "Host: www.example.org\r\n"
8523 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238524 };
8525
8526 MockRead data_reads1[] = {
8527 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8528 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8529 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068530 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238531 };
8532
[email protected]2262e3a2012-05-22 16:08:168533 // After the challenge above, the transaction will be restarted using the
8534 // identity from the url (foo, b@r) to answer the challenge.
8535 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238536 MockWrite(
8537 "GET / HTTP/1.1\r\n"
8538 "Host: www.example.org\r\n"
8539 "Connection: keep-alive\r\n"
8540 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168541 };
8542
8543 MockRead data_reads2[] = {
8544 MockRead("HTTP/1.0 200 OK\r\n"),
8545 MockRead("Content-Length: 100\r\n\r\n"),
8546 MockRead(SYNCHRONOUS, OK),
8547 };
8548
Ryan Sleevib8d7ea02018-05-07 20:01:018549 StaticSocketDataProvider data1(data_reads1, data_writes1);
8550 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078551 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8552 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238553
[email protected]49639fa2011-12-20 23:22:418554 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208555 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018556 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238557 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018558 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168559 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168560
8561 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168562 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018563 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168564 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018565 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168566 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228567
bnc691fda62016-08-12 00:43:168568 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528569 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168570
8571 // There is no challenge info, since the identity in URL worked.
Emily Starkf2c9bbd2019-04-09 17:08:588572 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]2262e3a2012-05-22 16:08:168573
8574 EXPECT_EQ(100, response->headers->GetContentLength());
8575
8576 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558577 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:168578}
8579
8580// Test the request-challenge-retry sequence for basic auth when there is an
8581// incorrect identity in the URL. The identity from the URL should be used only
8582// once.
bncd16676a2016-07-20 16:23:018583TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:168584 HttpRequestInfo request;
8585 request.method = "GET";
8586 // Note: the URL has a username:password in it. The password "baz" is
8587 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:238588 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:168589
8590 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:108591 request.traffic_annotation =
8592 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:168593
danakj1fd259a02016-04-16 03:17:098594 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168595 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:168596
8597 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238598 MockWrite(
8599 "GET / HTTP/1.1\r\n"
8600 "Host: www.example.org\r\n"
8601 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168602 };
8603
8604 MockRead data_reads1[] = {
8605 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8606 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8607 MockRead("Content-Length: 10\r\n\r\n"),
8608 MockRead(SYNCHRONOUS, ERR_FAILED),
8609 };
8610
8611 // After the challenge above, the transaction will be restarted using the
8612 // identity from the url (foo, baz) to answer the challenge.
8613 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238614 MockWrite(
8615 "GET / HTTP/1.1\r\n"
8616 "Host: www.example.org\r\n"
8617 "Connection: keep-alive\r\n"
8618 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168619 };
8620
8621 MockRead data_reads2[] = {
8622 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8623 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8624 MockRead("Content-Length: 10\r\n\r\n"),
8625 MockRead(SYNCHRONOUS, ERR_FAILED),
8626 };
8627
8628 // After the challenge above, the transaction will be restarted using the
8629 // identity supplied by the user (foo, bar) to answer the challenge.
8630 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238631 MockWrite(
8632 "GET / HTTP/1.1\r\n"
8633 "Host: www.example.org\r\n"
8634 "Connection: keep-alive\r\n"
8635 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168636 };
8637
8638 MockRead data_reads3[] = {
8639 MockRead("HTTP/1.0 200 OK\r\n"),
8640 MockRead("Content-Length: 100\r\n\r\n"),
8641 MockRead(SYNCHRONOUS, OK),
8642 };
8643
Ryan Sleevib8d7ea02018-05-07 20:01:018644 StaticSocketDataProvider data1(data_reads1, data_writes1);
8645 StaticSocketDataProvider data2(data_reads2, data_writes2);
8646 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:078647 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8648 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8649 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:168650
8651 TestCompletionCallback callback1;
8652
tfarina42834112016-09-22 13:38:208653 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018654 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168655
8656 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018657 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:168658
bnc691fda62016-08-12 00:43:168659 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168660 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168661 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018662 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168663 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018664 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168665 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168666
bnc691fda62016-08-12 00:43:168667 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528668 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:588669 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]2262e3a2012-05-22 16:08:168670
8671 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168672 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018673 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168674 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018675 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168676 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168677
bnc691fda62016-08-12 00:43:168678 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528679 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168680
8681 // There is no challenge info, since the identity worked.
Emily Starkf2c9bbd2019-04-09 17:08:588682 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]2262e3a2012-05-22 16:08:168683
8684 EXPECT_EQ(100, response->headers->GetContentLength());
8685
[email protected]ea9dc9a2009-09-05 00:43:328686 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558687 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:328688}
8689
[email protected]2217aa22013-10-11 03:03:548690
8691// Test the request-challenge-retry sequence for basic auth when there is a
8692// correct identity in the URL, but its use is being suppressed. The identity
8693// from the URL should never be used.
bncd16676a2016-07-20 16:23:018694TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:548695 HttpRequestInfo request;
8696 request.method = "GET";
bncce36dca22015-04-21 22:11:238697 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:548698 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e62018-02-07 07:41:108699 request.traffic_annotation =
8700 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:548701
danakj1fd259a02016-04-16 03:17:098702 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168703 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:548704
8705 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238706 MockWrite(
8707 "GET / HTTP/1.1\r\n"
8708 "Host: www.example.org\r\n"
8709 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548710 };
8711
8712 MockRead data_reads1[] = {
8713 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8714 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8715 MockRead("Content-Length: 10\r\n\r\n"),
8716 MockRead(SYNCHRONOUS, ERR_FAILED),
8717 };
8718
8719 // After the challenge above, the transaction will be restarted using the
8720 // identity supplied by the user, not the one in the URL, to answer the
8721 // challenge.
8722 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238723 MockWrite(
8724 "GET / HTTP/1.1\r\n"
8725 "Host: www.example.org\r\n"
8726 "Connection: keep-alive\r\n"
8727 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548728 };
8729
8730 MockRead data_reads3[] = {
8731 MockRead("HTTP/1.0 200 OK\r\n"),
8732 MockRead("Content-Length: 100\r\n\r\n"),
8733 MockRead(SYNCHRONOUS, OK),
8734 };
8735
Ryan Sleevib8d7ea02018-05-07 20:01:018736 StaticSocketDataProvider data1(data_reads1, data_writes1);
8737 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]2217aa22013-10-11 03:03:548738 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8739 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8740
8741 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208742 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018743 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548744 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018745 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168746 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548747
bnc691fda62016-08-12 00:43:168748 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528749 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:588750 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]2217aa22013-10-11 03:03:548751
8752 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168753 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018754 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548755 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018756 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168757 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548758
bnc691fda62016-08-12 00:43:168759 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528760 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548761
8762 // There is no challenge info, since the identity worked.
Emily Starkf2c9bbd2019-04-09 17:08:588763 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]2217aa22013-10-11 03:03:548764 EXPECT_EQ(100, response->headers->GetContentLength());
8765
8766 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558767 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:548768}
8769
[email protected]f9ee6b52008-11-08 06:46:238770// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:018771TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:098772 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:238773
8774 // Transaction 1: authenticate (foo, bar) on MyRealm1
8775 {
[email protected]1c773ea12009-04-28 19:58:428776 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238777 request.method = "GET";
bncce36dca22015-04-21 22:11:238778 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:108779 request.traffic_annotation =
8780 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238781
bnc691fda62016-08-12 00:43:168782 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278783
[email protected]f9ee6b52008-11-08 06:46:238784 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238785 MockWrite(
8786 "GET /x/y/z HTTP/1.1\r\n"
8787 "Host: www.example.org\r\n"
8788 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238789 };
8790
8791 MockRead data_reads1[] = {
8792 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8793 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8794 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068795 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238796 };
8797
8798 // Resend with authorization (username=foo, password=bar)
8799 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238800 MockWrite(
8801 "GET /x/y/z HTTP/1.1\r\n"
8802 "Host: www.example.org\r\n"
8803 "Connection: keep-alive\r\n"
8804 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238805 };
8806
8807 // Sever accepts the authorization.
8808 MockRead data_reads2[] = {
8809 MockRead("HTTP/1.0 200 OK\r\n"),
8810 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068811 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238812 };
8813
Ryan Sleevib8d7ea02018-05-07 20:01:018814 StaticSocketDataProvider data1(data_reads1, data_writes1);
8815 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078816 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8817 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238818
[email protected]49639fa2011-12-20 23:22:418819 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238820
tfarina42834112016-09-22 13:38:208821 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238823
8824 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018825 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238826
bnc691fda62016-08-12 00:43:168827 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528828 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:588829 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]f9ee6b52008-11-08 06:46:238830
[email protected]49639fa2011-12-20 23:22:418831 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238832
bnc691fda62016-08-12 00:43:168833 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8834 callback2.callback());
robpercival214763f2016-07-01 23:27:018835 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238836
8837 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018838 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238839
bnc691fda62016-08-12 00:43:168840 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528841 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:588842 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]f9ee6b52008-11-08 06:46:238843 EXPECT_EQ(100, response->headers->GetContentLength());
8844 }
8845
8846 // ------------------------------------------------------------------------
8847
8848 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
8849 {
[email protected]1c773ea12009-04-28 19:58:428850 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238851 request.method = "GET";
8852 // Note that Transaction 1 was at /x/y/z, so this is in the same
8853 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:238854 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:108855 request.traffic_annotation =
8856 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238857
bnc691fda62016-08-12 00:43:168858 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278859
[email protected]f9ee6b52008-11-08 06:46:238860 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238861 MockWrite(
8862 "GET /x/y/a/b HTTP/1.1\r\n"
8863 "Host: www.example.org\r\n"
8864 "Connection: keep-alive\r\n"
8865 // Send preemptive authorization for MyRealm1
8866 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238867 };
8868
8869 // The server didn't like the preemptive authorization, and
8870 // challenges us for a different realm (MyRealm2).
8871 MockRead data_reads1[] = {
8872 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8873 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8874 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068875 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238876 };
8877
8878 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8879 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238880 MockWrite(
8881 "GET /x/y/a/b HTTP/1.1\r\n"
8882 "Host: www.example.org\r\n"
8883 "Connection: keep-alive\r\n"
8884 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238885 };
8886
8887 // Sever accepts the authorization.
8888 MockRead data_reads2[] = {
8889 MockRead("HTTP/1.0 200 OK\r\n"),
8890 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068891 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238892 };
8893
Ryan Sleevib8d7ea02018-05-07 20:01:018894 StaticSocketDataProvider data1(data_reads1, data_writes1);
8895 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078896 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8897 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238898
[email protected]49639fa2011-12-20 23:22:418899 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238900
tfarina42834112016-09-22 13:38:208901 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018902 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238903
8904 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018905 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238906
bnc691fda62016-08-12 00:43:168907 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528908 ASSERT_TRUE(response);
8909 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048910 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438911 EXPECT_EQ("http://www.example.org",
8912 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048913 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198914 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238915
[email protected]49639fa2011-12-20 23:22:418916 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238917
bnc691fda62016-08-12 00:43:168918 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8919 callback2.callback());
robpercival214763f2016-07-01 23:27:018920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238921
8922 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018923 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238924
bnc691fda62016-08-12 00:43:168925 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528926 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:588927 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]f9ee6b52008-11-08 06:46:238928 EXPECT_EQ(100, response->headers->GetContentLength());
8929 }
8930
8931 // ------------------------------------------------------------------------
8932
8933 // Transaction 3: Resend a request in MyRealm's protection space --
8934 // succeed with preemptive authorization.
8935 {
[email protected]1c773ea12009-04-28 19:58:428936 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238937 request.method = "GET";
bncce36dca22015-04-21 22:11:238938 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e62018-02-07 07:41:108939 request.traffic_annotation =
8940 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238941
bnc691fda62016-08-12 00:43:168942 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278943
[email protected]f9ee6b52008-11-08 06:46:238944 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238945 MockWrite(
8946 "GET /x/y/z2 HTTP/1.1\r\n"
8947 "Host: www.example.org\r\n"
8948 "Connection: keep-alive\r\n"
8949 // The authorization for MyRealm1 gets sent preemptively
8950 // (since the url is in the same protection space)
8951 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238952 };
8953
8954 // Sever accepts the preemptive authorization
8955 MockRead data_reads1[] = {
8956 MockRead("HTTP/1.0 200 OK\r\n"),
8957 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068958 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238959 };
8960
Ryan Sleevib8d7ea02018-05-07 20:01:018961 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078962 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238963
[email protected]49639fa2011-12-20 23:22:418964 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238965
tfarina42834112016-09-22 13:38:208966 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018967 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238968
8969 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018970 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238971
bnc691fda62016-08-12 00:43:168972 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528973 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238974
Emily Starkf2c9bbd2019-04-09 17:08:588975 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]f9ee6b52008-11-08 06:46:238976 EXPECT_EQ(100, response->headers->GetContentLength());
8977 }
8978
8979 // ------------------------------------------------------------------------
8980
8981 // Transaction 4: request another URL in MyRealm (however the
8982 // url is not known to belong to the protection space, so no pre-auth).
8983 {
[email protected]1c773ea12009-04-28 19:58:428984 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238985 request.method = "GET";
bncce36dca22015-04-21 22:11:238986 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e62018-02-07 07:41:108987 request.traffic_annotation =
8988 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238989
bnc691fda62016-08-12 00:43:168990 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278991
[email protected]f9ee6b52008-11-08 06:46:238992 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238993 MockWrite(
8994 "GET /x/1 HTTP/1.1\r\n"
8995 "Host: www.example.org\r\n"
8996 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238997 };
8998
8999 MockRead data_reads1[] = {
9000 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9001 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9002 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069003 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239004 };
9005
9006 // Resend with authorization from MyRealm's cache.
9007 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239008 MockWrite(
9009 "GET /x/1 HTTP/1.1\r\n"
9010 "Host: www.example.org\r\n"
9011 "Connection: keep-alive\r\n"
9012 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239013 };
9014
9015 // Sever accepts the authorization.
9016 MockRead data_reads2[] = {
9017 MockRead("HTTP/1.0 200 OK\r\n"),
9018 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069019 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239020 };
9021
Ryan Sleevib8d7ea02018-05-07 20:01:019022 StaticSocketDataProvider data1(data_reads1, data_writes1);
9023 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079024 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9025 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:239026
[email protected]49639fa2011-12-20 23:22:419027 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239028
tfarina42834112016-09-22 13:38:209029 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019030 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239031
9032 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019033 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239034
bnc691fda62016-08-12 00:43:169035 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419036 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169037 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019038 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229039 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019040 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169041 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229042
bnc691fda62016-08-12 00:43:169043 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529044 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589045 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]f9ee6b52008-11-08 06:46:239046 EXPECT_EQ(100, response->headers->GetContentLength());
9047 }
9048
9049 // ------------------------------------------------------------------------
9050
9051 // Transaction 5: request a URL in MyRealm, but the server rejects the
9052 // cached identity. Should invalidate and re-prompt.
9053 {
[email protected]1c773ea12009-04-28 19:58:429054 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:239055 request.method = "GET";
bncce36dca22015-04-21 22:11:239056 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e62018-02-07 07:41:109057 request.traffic_annotation =
9058 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:239059
bnc691fda62016-08-12 00:43:169060 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279061
[email protected]f9ee6b52008-11-08 06:46:239062 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239063 MockWrite(
9064 "GET /p/q/t HTTP/1.1\r\n"
9065 "Host: www.example.org\r\n"
9066 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239067 };
9068
9069 MockRead data_reads1[] = {
9070 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9071 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9072 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069073 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239074 };
9075
9076 // Resend with authorization from cache for MyRealm.
9077 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239078 MockWrite(
9079 "GET /p/q/t HTTP/1.1\r\n"
9080 "Host: www.example.org\r\n"
9081 "Connection: keep-alive\r\n"
9082 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239083 };
9084
9085 // Sever rejects the authorization.
9086 MockRead data_reads2[] = {
9087 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9088 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9089 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069090 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239091 };
9092
9093 // At this point we should prompt for new credentials for MyRealm.
9094 // Restart with username=foo3, password=foo4.
9095 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239096 MockWrite(
9097 "GET /p/q/t HTTP/1.1\r\n"
9098 "Host: www.example.org\r\n"
9099 "Connection: keep-alive\r\n"
9100 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239101 };
9102
9103 // Sever accepts the authorization.
9104 MockRead data_reads3[] = {
9105 MockRead("HTTP/1.0 200 OK\r\n"),
9106 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069107 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239108 };
9109
Ryan Sleevib8d7ea02018-05-07 20:01:019110 StaticSocketDataProvider data1(data_reads1, data_writes1);
9111 StaticSocketDataProvider data2(data_reads2, data_writes2);
9112 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:079113 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9114 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9115 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:239116
[email protected]49639fa2011-12-20 23:22:419117 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239118
tfarina42834112016-09-22 13:38:209119 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019120 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239121
9122 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019123 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239124
bnc691fda62016-08-12 00:43:169125 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419126 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169127 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019128 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229129 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019130 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169131 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229132
bnc691fda62016-08-12 00:43:169133 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529134 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589135 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]f9ee6b52008-11-08 06:46:239136
[email protected]49639fa2011-12-20 23:22:419137 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:239138
bnc691fda62016-08-12 00:43:169139 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
9140 callback3.callback());
robpercival214763f2016-07-01 23:27:019141 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239142
[email protected]0757e7702009-03-27 04:00:229143 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:019144 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239145
bnc691fda62016-08-12 00:43:169146 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529147 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589148 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]f9ee6b52008-11-08 06:46:239149 EXPECT_EQ(100, response->headers->GetContentLength());
9150 }
9151}
[email protected]89ceba9a2009-03-21 03:46:069152
[email protected]3c32c5f2010-05-18 15:18:129153// Tests that nonce count increments when multiple auth attempts
9154// are started with the same nonce.
bncd16676a2016-07-20 16:23:019155TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:449156 HttpAuthHandlerDigest::Factory* digest_factory =
9157 new HttpAuthHandlerDigest::Factory();
9158 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
9159 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
9160 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:079161 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:099162 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:129163
9164 // Transaction 1: authenticate (foo, bar) on MyRealm1
9165 {
[email protected]3c32c5f2010-05-18 15:18:129166 HttpRequestInfo request;
9167 request.method = "GET";
bncce36dca22015-04-21 22:11:239168 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:109169 request.traffic_annotation =
9170 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129171
bnc691fda62016-08-12 00:43:169172 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279173
[email protected]3c32c5f2010-05-18 15:18:129174 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239175 MockWrite(
9176 "GET /x/y/z HTTP/1.1\r\n"
9177 "Host: www.example.org\r\n"
9178 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129179 };
9180
9181 MockRead data_reads1[] = {
9182 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9183 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
9184 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069185 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129186 };
9187
9188 // Resend with authorization (username=foo, password=bar)
9189 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239190 MockWrite(
9191 "GET /x/y/z HTTP/1.1\r\n"
9192 "Host: www.example.org\r\n"
9193 "Connection: keep-alive\r\n"
9194 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9195 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
9196 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
9197 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129198 };
9199
9200 // Sever accepts the authorization.
9201 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:089202 MockRead("HTTP/1.0 200 OK\r\n"),
9203 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129204 };
9205
Ryan Sleevib8d7ea02018-05-07 20:01:019206 StaticSocketDataProvider data1(data_reads1, data_writes1);
9207 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079208 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9209 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:129210
[email protected]49639fa2011-12-20 23:22:419211 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129212
tfarina42834112016-09-22 13:38:209213 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019214 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129215
9216 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019217 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129218
bnc691fda62016-08-12 00:43:169219 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529220 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589221 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge));
[email protected]3c32c5f2010-05-18 15:18:129222
[email protected]49639fa2011-12-20 23:22:419223 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:129224
bnc691fda62016-08-12 00:43:169225 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
9226 callback2.callback());
robpercival214763f2016-07-01 23:27:019227 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129228
9229 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019230 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129231
bnc691fda62016-08-12 00:43:169232 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529233 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589234 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]3c32c5f2010-05-18 15:18:129235 }
9236
9237 // ------------------------------------------------------------------------
9238
9239 // Transaction 2: Request another resource in digestive's protection space.
9240 // This will preemptively add an Authorization header which should have an
9241 // "nc" value of 2 (as compared to 1 in the first use.
9242 {
[email protected]3c32c5f2010-05-18 15:18:129243 HttpRequestInfo request;
9244 request.method = "GET";
9245 // Note that Transaction 1 was at /x/y/z, so this is in the same
9246 // protection space as digest.
bncce36dca22015-04-21 22:11:239247 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:109248 request.traffic_annotation =
9249 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129250
bnc691fda62016-08-12 00:43:169251 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279252
[email protected]3c32c5f2010-05-18 15:18:129253 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239254 MockWrite(
9255 "GET /x/y/a/b HTTP/1.1\r\n"
9256 "Host: www.example.org\r\n"
9257 "Connection: keep-alive\r\n"
9258 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9259 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
9260 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
9261 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129262 };
9263
9264 // Sever accepts the authorization.
9265 MockRead data_reads1[] = {
9266 MockRead("HTTP/1.0 200 OK\r\n"),
9267 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069268 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129269 };
9270
Ryan Sleevib8d7ea02018-05-07 20:01:019271 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:079272 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:129273
[email protected]49639fa2011-12-20 23:22:419274 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129275
tfarina42834112016-09-22 13:38:209276 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019277 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129278
9279 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019280 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129281
bnc691fda62016-08-12 00:43:169282 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529283 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589284 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]3c32c5f2010-05-18 15:18:129285 }
9286}
9287
[email protected]89ceba9a2009-03-21 03:46:069288// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:019289TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:069290 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:099291 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169292 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:069293
9294 // Setup some state (which we expect ResetStateForRestart() will clear).
Victor Costan9c7302b2018-08-27 16:39:449295 trans.read_buf_ = base::MakeRefCounted<IOBuffer>(15);
bnc691fda62016-08-12 00:43:169296 trans.read_buf_len_ = 15;
9297 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:069298
9299 // Setup state in response_
bnc691fda62016-08-12 00:43:169300 HttpResponseInfo* response = &trans.response_;
Emily Starkf2c9bbd2019-04-09 17:08:589301 response->auth_challenge = base::nullopt;
[email protected]70d66502011-09-23 00:55:089302 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:579303 response->response_time = base::Time::Now();
9304 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:069305
9306 { // Setup state for response_.vary_data
9307 HttpRequestInfo request;
9308 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
9309 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:279310 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:439311 request.extra_headers.SetHeader("Foo", "1");
9312 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:509313 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:069314 }
9315
9316 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:169317 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:069318
9319 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:169320 EXPECT_FALSE(trans.read_buf_);
9321 EXPECT_EQ(0, trans.read_buf_len_);
9322 EXPECT_TRUE(trans.request_headers_.IsEmpty());
Emily Starkf2c9bbd2019-04-09 17:08:589323 EXPECT_FALSE(response->auth_challenge.has_value());
wezca1070932016-05-26 20:30:529324 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:049325 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:089326 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:579327 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:069328}
9329
[email protected]bacff652009-03-31 17:50:339330// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:019331TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:339332 HttpRequestInfo request;
9333 request.method = "GET";
bncce36dca22015-04-21 22:11:239334 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109335 request.traffic_annotation =
9336 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339337
danakj1fd259a02016-04-16 03:17:099338 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169339 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279340
[email protected]bacff652009-03-31 17:50:339341 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239342 MockWrite(
9343 "GET / HTTP/1.1\r\n"
9344 "Host: www.example.org\r\n"
9345 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339346 };
9347
9348 MockRead data_reads[] = {
9349 MockRead("HTTP/1.0 200 OK\r\n"),
9350 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9351 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069352 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339353 };
9354
[email protected]5ecc992a42009-11-11 01:41:599355 StaticSocketDataProvider ssl_bad_certificate;
Ryan Sleevib8d7ea02018-05-07 20:01:019356 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069357 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9358 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339359
[email protected]bb88e1d32013-05-03 23:11:079360 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9361 session_deps_.socket_factory->AddSocketDataProvider(&data);
9362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9363 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339364
[email protected]49639fa2011-12-20 23:22:419365 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339366
tfarina42834112016-09-22 13:38:209367 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019368 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339369
9370 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019371 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339372
bnc691fda62016-08-12 00:43:169373 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019374 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339375
9376 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019377 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339378
bnc691fda62016-08-12 00:43:169379 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339380
wezca1070932016-05-26 20:30:529381 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339382 EXPECT_EQ(100, response->headers->GetContentLength());
9383}
9384
9385// Test HTTPS connections to a site with a bad certificate, going through a
9386// proxy
bncd16676a2016-07-20 16:23:019387TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499388 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9389 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339390
9391 HttpRequestInfo request;
9392 request.method = "GET";
bncce36dca22015-04-21 22:11:239393 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109394 request.traffic_annotation =
9395 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339396
9397 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:179398 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9399 "Host: www.example.org:443\r\n"
9400 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339401 };
9402
9403 MockRead proxy_reads[] = {
9404 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069405 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:339406 };
9407
9408 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179409 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9410 "Host: www.example.org:443\r\n"
9411 "Proxy-Connection: keep-alive\r\n\r\n"),
9412 MockWrite("GET / HTTP/1.1\r\n"
9413 "Host: www.example.org\r\n"
9414 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339415 };
9416
9417 MockRead data_reads[] = {
9418 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9419 MockRead("HTTP/1.0 200 OK\r\n"),
9420 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9421 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069422 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339423 };
9424
Ryan Sleevib8d7ea02018-05-07 20:01:019425 StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
9426 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069427 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9428 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339429
[email protected]bb88e1d32013-05-03 23:11:079430 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9431 session_deps_.socket_factory->AddSocketDataProvider(&data);
9432 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9433 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339434
[email protected]49639fa2011-12-20 23:22:419435 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339436
9437 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:079438 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:339439
danakj1fd259a02016-04-16 03:17:099440 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169441 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:339442
tfarina42834112016-09-22 13:38:209443 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019444 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339445
9446 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019447 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339448
bnc691fda62016-08-12 00:43:169449 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019450 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339451
9452 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019453 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339454
bnc691fda62016-08-12 00:43:169455 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339456
wezca1070932016-05-26 20:30:529457 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339458 EXPECT_EQ(100, response->headers->GetContentLength());
9459 }
9460}
9461
[email protected]2df19bb2010-08-25 20:13:469462
9463// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:019464TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599465 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499466 ProxyResolutionService::CreateFixedFromPacResult(
9467 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519468 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079469 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:469470
9471 HttpRequestInfo request;
9472 request.method = "GET";
bncce36dca22015-04-21 22:11:239473 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109474 request.traffic_annotation =
9475 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469476
9477 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179478 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9479 "Host: www.example.org:443\r\n"
9480 "Proxy-Connection: keep-alive\r\n\r\n"),
9481 MockWrite("GET / HTTP/1.1\r\n"
9482 "Host: www.example.org\r\n"
9483 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469484 };
9485
9486 MockRead data_reads[] = {
9487 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9488 MockRead("HTTP/1.1 200 OK\r\n"),
9489 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9490 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069491 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469492 };
9493
Ryan Sleevib8d7ea02018-05-07 20:01:019494 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069495 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9496 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:469497
[email protected]bb88e1d32013-05-03 23:11:079498 session_deps_.socket_factory->AddSocketDataProvider(&data);
9499 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9500 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:469501
[email protected]49639fa2011-12-20 23:22:419502 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469503
danakj1fd259a02016-04-16 03:17:099504 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169505 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469506
tfarina42834112016-09-22 13:38:209507 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019508 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469509
9510 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019511 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169512 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469513
wezca1070932016-05-26 20:30:529514 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469515
tbansal2ecbbc72016-10-06 17:15:479516 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:469517 EXPECT_TRUE(response->headers->IsKeepAlive());
9518 EXPECT_EQ(200, response->headers->response_code());
9519 EXPECT_EQ(100, response->headers->GetContentLength());
9520 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209521
9522 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169523 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209524 TestLoadTimingNotReusedWithPac(load_timing_info,
9525 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:469526}
9527
Eric Roman695a7872019-04-16 21:53:299528// Test that an HTTPS Proxy cannot redirect a CONNECT request for main frames.
bncd16676a2016-07-20 16:23:019529TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599530 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499531 ProxyResolutionService::CreateFixedFromPacResult(
9532 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519533 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079534 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:299535
Matt Menkeecfecfc72019-02-05 19:15:289536 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9537 session_deps_.host_resolver->set_ondemand_mode(true);
9538
[email protected]511f6f52010-12-17 03:58:299539 HttpRequestInfo request;
Eric Roman74103c72019-02-21 00:23:129540 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
[email protected]511f6f52010-12-17 03:58:299541 request.method = "GET";
bncce36dca22015-04-21 22:11:239542 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109543 request.traffic_annotation =
9544 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299545
9546 MockWrite data_writes[] = {
Matt Menkeecfecfc72019-02-05 19:15:289547 MockWrite(ASYNC, 0,
9548 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:179549 "Host: www.example.org:443\r\n"
9550 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299551 };
9552
9553 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289554 // Pause on first read.
9555 MockRead(ASYNC, ERR_IO_PENDING, 1),
9556 MockRead(ASYNC, 2, "HTTP/1.1 302 Redirect\r\n"),
9557 MockRead(ASYNC, 3, "Location: http://login.example.com/\r\n"),
9558 MockRead(ASYNC, 4, "Content-Length: 0\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299559 };
9560
Matt Menkeecfecfc72019-02-05 19:15:289561 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069562 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299563
[email protected]bb88e1d32013-05-03 23:11:079564 session_deps_.socket_factory->AddSocketDataProvider(&data);
9565 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299566
[email protected]49639fa2011-12-20 23:22:419567 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299568
danakj1fd259a02016-04-16 03:17:099569 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169570 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299571
tfarina42834112016-09-22 13:38:209572 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019573 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289574 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
9575
9576 // Host resolution takes |kTimeIncrement|.
9577 FastForwardBy(kTimeIncrement);
9578 // Resolving the current request with |ResolveNow| will cause the pending
9579 // request to instantly complete, and the async connect will start as well.
9580 session_deps_.host_resolver->ResolveOnlyRequestNow();
9581
9582 // Connecting takes |kTimeIncrement|.
9583 FastForwardBy(kTimeIncrement);
9584 data.RunUntilPaused();
9585
9586 // The server takes |kTimeIncrement| to respond.
9587 FastForwardBy(kTimeIncrement);
9588 data.Resume();
[email protected]511f6f52010-12-17 03:58:299589
9590 rv = callback.WaitForResult();
Eric Roman695a7872019-04-16 21:53:299591 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
[email protected]511f6f52010-12-17 03:58:299592}
9593
Eric Roman74103c72019-02-21 00:23:129594// Test that an HTTPS Proxy cannot redirect a CONNECT request for subresources.
9595TEST_F(HttpNetworkTransactionTest,
9596 RedirectOfHttpsConnectSubresourceViaHttpsProxy) {
9597 base::HistogramTester histograms;
9598 session_deps_.proxy_resolution_service =
9599 ProxyResolutionService::CreateFixedFromPacResult(
9600 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9601 TestNetLog net_log;
9602 session_deps_.net_log = &net_log;
9603
9604 HttpRequestInfo request;
9605 request.method = "GET";
9606 request.url = GURL("https://www.example.org/");
9607 request.traffic_annotation =
9608 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9609
9610 MockWrite data_writes[] = {
9611 MockWrite(ASYNC, 0,
9612 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9613 "Host: www.example.org:443\r\n"
9614 "Proxy-Connection: keep-alive\r\n\r\n"),
9615 };
9616
9617 MockRead data_reads[] = {
9618 MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
9619 MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
9620 MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
9621 };
9622
9623 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
9624 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9625
9626 session_deps_.socket_factory->AddSocketDataProvider(&data);
9627 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9628
9629 TestCompletionCallback callback;
9630
9631 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9632 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9633
9634 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9635 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9636
9637 rv = callback.WaitForResult();
9638 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
9639
9640 histograms.ExpectUniqueSample(
9641 "Net.Proxy.RedirectDuringConnect",
9642 HttpNetworkTransaction::kSubresourceByExplicitProxy, 1);
9643}
9644
9645// Test that an HTTPS Proxy which was auto-detected cannot redirect a CONNECT
9646// request for main frames.
9647TEST_F(HttpNetworkTransactionTest,
9648 RedirectOfHttpsConnectViaAutoDetectedHttpsProxy) {
9649 base::HistogramTester histograms;
9650 session_deps_.proxy_resolution_service =
9651 ProxyResolutionService::CreateFixedFromAutoDetectedPacResult(
9652 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9653 TestNetLog net_log;
9654 session_deps_.net_log = &net_log;
9655
9656 HttpRequestInfo request;
9657 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
9658 request.method = "GET";
9659 request.url = GURL("https://www.example.org/");
9660 request.traffic_annotation =
9661 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9662
9663 MockWrite data_writes[] = {
9664 MockWrite(ASYNC, 0,
9665 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9666 "Host: www.example.org:443\r\n"
9667 "Proxy-Connection: keep-alive\r\n\r\n"),
9668 };
9669
9670 MockRead data_reads[] = {
9671 MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
9672 MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
9673 MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
9674 };
9675
9676 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
9677 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9678
9679 session_deps_.socket_factory->AddSocketDataProvider(&data);
9680 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9681
9682 TestCompletionCallback callback;
9683
9684 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9685 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9686
9687 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9688 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9689
9690 rv = callback.WaitForResult();
9691 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
9692
9693 histograms.ExpectUniqueSample(
9694 "Net.Proxy.RedirectDuringConnect",
9695 HttpNetworkTransaction::kMainFrameByAutoDetectedProxy, 1);
9696}
9697
Eric Roman695a7872019-04-16 21:53:299698// Tests that an HTTPS (SPDY) Proxy's cannot redirect a CONNECT request for main
Eric Roman74103c72019-02-21 00:23:129699// frames.
bncd16676a2016-07-20 16:23:019700TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Eric Roman74103c72019-02-21 00:23:129701 base::HistogramTester histograms;
Ramin Halavatica8d5252018-03-12 05:33:499702 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9703 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeecfecfc72019-02-05 19:15:289704 TestNetLog net_log;
9705 session_deps_.net_log = &net_log;
9706
Matt Menkeecfecfc72019-02-05 19:15:289707 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9708 session_deps_.host_resolver->set_ondemand_mode(true);
[email protected]511f6f52010-12-17 03:58:299709
9710 HttpRequestInfo request;
9711 request.method = "GET";
Eric Roman74103c72019-02-21 00:23:129712 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
bncce36dca22015-04-21 22:11:239713 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109714 request.traffic_annotation =
9715 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299716
Ryan Hamilton0239aac2018-05-19 00:03:139717 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049718 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9719 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139720 spdy::SpdySerializedFrame goaway(
9721 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299722 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419723 CreateMockWrite(conn, 0, SYNCHRONOUS),
Matt Menkeecfecfc72019-02-05 19:15:289724 CreateMockWrite(goaway, 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:299725 };
9726
9727 static const char* const kExtraHeaders[] = {
9728 "location",
9729 "http://login.example.com/",
9730 };
Ryan Hamilton0239aac2018-05-19 00:03:139731 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249732 "302", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:299733 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289734 // Pause on first read.
9735 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2),
9736 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299737 };
9738
Matt Menkeecfecfc72019-02-05 19:15:289739 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069740 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369741 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299742
[email protected]bb88e1d32013-05-03 23:11:079743 session_deps_.socket_factory->AddSocketDataProvider(&data);
9744 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299745
[email protected]49639fa2011-12-20 23:22:419746 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299747
danakj1fd259a02016-04-16 03:17:099748 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169749 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299750
tfarina42834112016-09-22 13:38:209751 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019752 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289753 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
[email protected]511f6f52010-12-17 03:58:299754
Matt Menkeecfecfc72019-02-05 19:15:289755 // Host resolution takes |kTimeIncrement|.
9756 FastForwardBy(kTimeIncrement);
9757 // Resolving the current request with |ResolveNow| will cause the pending
9758 // request to instantly complete, and the async connect will start as well.
9759 session_deps_.host_resolver->ResolveOnlyRequestNow();
9760
9761 // Connecting takes |kTimeIncrement|.
9762 FastForwardBy(kTimeIncrement);
9763 data.RunUntilPaused();
9764
9765 FastForwardBy(kTimeIncrement);
9766 data.Resume();
[email protected]511f6f52010-12-17 03:58:299767 rv = callback.WaitForResult();
Eric Roman695a7872019-04-16 21:53:299768 EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT));
Eric Roman74103c72019-02-21 00:23:129769
9770 histograms.ExpectUniqueSample(
9771 "Net.Proxy.RedirectDuringConnect",
9772 HttpNetworkTransaction::kMainFrameByExplicitProxy, 1);
[email protected]511f6f52010-12-17 03:58:299773}
9774
[email protected]4eddbc732012-08-09 05:40:179775// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019776TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499777 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9778 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299779
9780 HttpRequestInfo request;
9781 request.method = "GET";
bncce36dca22015-04-21 22:11:239782 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109783 request.traffic_annotation =
9784 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299785
9786 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179787 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9788 "Host: www.example.org:443\r\n"
9789 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299790 };
9791
9792 MockRead data_reads[] = {
9793 MockRead("HTTP/1.1 404 Not Found\r\n"),
9794 MockRead("Content-Length: 23\r\n\r\n"),
9795 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:069796 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:299797 };
9798
Ryan Sleevib8d7ea02018-05-07 20:01:019799 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069800 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299801
[email protected]bb88e1d32013-05-03 23:11:079802 session_deps_.socket_factory->AddSocketDataProvider(&data);
9803 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299804
[email protected]49639fa2011-12-20 23:22:419805 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299806
danakj1fd259a02016-04-16 03:17:099807 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169808 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299809
tfarina42834112016-09-22 13:38:209810 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019811 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299812
9813 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019814 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299815
ttuttle960fcbf2016-04-19 13:26:329816 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299817}
9818
[email protected]4eddbc732012-08-09 05:40:179819// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019820TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499821 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9822 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299823
9824 HttpRequestInfo request;
9825 request.method = "GET";
bncce36dca22015-04-21 22:11:239826 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109827 request.traffic_annotation =
9828 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299829
Ryan Hamilton0239aac2018-05-19 00:03:139830 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049831 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9832 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139833 spdy::SpdySerializedFrame rst(
9834 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299835 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419836 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:299837 };
9838
9839 static const char* const kExtraHeaders[] = {
9840 "location",
9841 "http://login.example.com/",
9842 };
Ryan Hamilton0239aac2018-05-19 00:03:139843 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249844 "404", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:139845 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:199846 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:299847 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:419848 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:139849 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299850 };
9851
Ryan Sleevib8d7ea02018-05-07 20:01:019852 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069853 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369854 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299855
[email protected]bb88e1d32013-05-03 23:11:079856 session_deps_.socket_factory->AddSocketDataProvider(&data);
9857 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299858
[email protected]49639fa2011-12-20 23:22:419859 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299860
danakj1fd259a02016-04-16 03:17:099861 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169862 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299863
tfarina42834112016-09-22 13:38:209864 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019865 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299866
9867 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019868 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299869
ttuttle960fcbf2016-04-19 13:26:329870 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299871}
9872
[email protected]0c5fb722012-02-28 11:50:359873// Test the request-challenge-retry sequence for basic auth, through
9874// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:019875TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:359876 HttpRequestInfo request;
9877 request.method = "GET";
bncce36dca22015-04-21 22:11:239878 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:359879 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:299880 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:109881 request.traffic_annotation =
9882 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:359883
9884 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599885 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499886 ProxyResolutionService::CreateFixedFromPacResult(
9887 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519888 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079889 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:099890 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:359891
9892 // Since we have proxy, should try to establish tunnel.
Ryan Hamilton0239aac2018-05-19 00:03:139893 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049894 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9895 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139896 spdy::SpdySerializedFrame rst(
9897 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:389898 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:359899
bnc691fda62016-08-12 00:43:169900 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:359901 // be issuing -- the final header line contains the credentials.
9902 const char* const kAuthCredentials[] = {
9903 "proxy-authorization", "Basic Zm9vOmJhcg==",
9904 };
Ryan Hamilton0239aac2018-05-19 00:03:139905 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049906 kAuthCredentials, base::size(kAuthCredentials) / 2, 3,
9907 HttpProxyConnectJob::kH2QuicTunnelPriority,
bncce36dca22015-04-21 22:11:239908 HostPortPair("www.example.org", 443)));
9909 // fetch https://www.example.org/ via HTTP
9910 const char get[] =
9911 "GET / HTTP/1.1\r\n"
9912 "Host: www.example.org\r\n"
9913 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:139914 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:199915 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:359916
9917 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419918 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
9919 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:359920 };
9921
9922 // The proxy responds to the connect with a 407, using a persistent
9923 // connection.
thestig9d3bb0c2015-01-24 00:49:519924 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:359925 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:359926 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
9927 };
Ryan Hamilton0239aac2018-05-19 00:03:139928 spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249929 kAuthStatus, kAuthChallenge, base::size(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:359930
Ryan Hamilton0239aac2018-05-19 00:03:139931 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:359932 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
[email protected]0c5fb722012-02-28 11:50:359933 const char resp[] = "HTTP/1.1 200 OK\r\n"
9934 "Content-Length: 5\r\n\r\n";
9935
Ryan Hamilton0239aac2018-05-19 00:03:139936 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:199937 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:139938 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:199939 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:359940 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419941 CreateMockRead(conn_auth_resp, 1, ASYNC),
9942 CreateMockRead(conn_resp, 4, ASYNC),
9943 CreateMockRead(wrapped_get_resp, 6, ASYNC),
9944 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:139945 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:359946 };
9947
Ryan Sleevib8d7ea02018-05-07 20:01:019948 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079949 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:359950 // Negotiate SPDY to the proxy
9951 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369952 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079953 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:359954 // Vanilla SSL to the server
9955 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079956 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:359957
9958 TestCompletionCallback callback1;
9959
bnc87dcefc2017-05-25 12:47:589960 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199961 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:359962
9963 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019964 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359965
9966 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019967 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:469968 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:359969 log.GetEntries(&entries);
9970 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:009971 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
9972 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359973 ExpectLogContainsSomewhere(
9974 entries, pos,
mikecirone8b85c432016-09-08 19:11:009975 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9976 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359977
9978 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529979 ASSERT_TRUE(response);
9980 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:359981 EXPECT_EQ(407, response->headers->response_code());
9982 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:589983 EXPECT_TRUE(response->auth_challenge.has_value());
9984 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
[email protected]0c5fb722012-02-28 11:50:359985
9986 TestCompletionCallback callback2;
9987
9988 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
9989 callback2.callback());
robpercival214763f2016-07-01 23:27:019990 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359991
9992 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019993 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:359994
9995 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529996 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:359997
9998 EXPECT_TRUE(response->headers->IsKeepAlive());
9999 EXPECT_EQ(200, response->headers->response_code());
10000 EXPECT_EQ(5, response->headers->GetContentLength());
10001 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10002
10003 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:5810004 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0c5fb722012-02-28 11:50:3510005
[email protected]029c83b62013-01-24 05:28:2010006 LoadTimingInfo load_timing_info;
10007 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10008 TestLoadTimingNotReusedWithPac(load_timing_info,
10009 CONNECT_TIMING_HAS_SSL_TIMES);
10010
[email protected]0c5fb722012-02-28 11:50:3510011 trans.reset();
10012 session->CloseAllConnections();
10013}
10014
[email protected]7c6f7ba2012-04-03 04:09:2910015// Test that an explicitly trusted SPDY proxy can push a resource from an
10016// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:0110017TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:1510018 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910019 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510020 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10021 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:2910022 HttpRequestInfo request;
10023 HttpRequestInfo push_request;
Ramin Halavatib5e433e62018-02-07 07:41:1010024 request.traffic_annotation =
10025 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:2910026
[email protected]7c6f7ba2012-04-03 04:09:2910027 request.method = "GET";
bncce36dca22015-04-21 22:11:2310028 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:2910029 push_request.method = "GET";
10030 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e62018-02-07 07:41:1010031 push_request.traffic_annotation =
10032 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:2910033
tbansal28e68f82016-02-04 02:56:1510034 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:5910035 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910036 ProxyResolutionService::CreateFixedFromPacResult(
10037 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110038 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710039 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010040
Eric Roman3d8546a2018-09-10 17:00:5210041 session_deps_.proxy_resolution_service->SetProxyDelegate(
10042 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010043
danakj1fd259a02016-04-16 03:17:0910044 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:2910045
Ryan Hamilton0239aac2018-05-19 00:03:1310046 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510047 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310048 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510049 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:2910050
10051 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110052 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510053 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:2910054 };
10055
Ryan Hamilton0239aac2018-05-19 00:03:1310056 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Raul Tambre94493c652019-03-11 17:18:3510057 nullptr, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
Bence Béky7bf94362018-01-10 13:19:3610058
Ryan Hamilton0239aac2018-05-19 00:03:1310059 spdy::SpdySerializedFrame stream1_reply(
Raul Tambre94493c652019-03-11 17:18:3510060 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:2910061
Ryan Hamilton0239aac2018-05-19 00:03:1310062 spdy::SpdySerializedFrame stream1_body(
10063 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:2910064
Ryan Hamilton0239aac2018-05-19 00:03:1310065 spdy::SpdySerializedFrame stream2_body(
Bence Békyd74f4382018-02-20 18:26:1910066 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:2910067
10068 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:3610069 CreateMockRead(stream2_syn, 1, ASYNC),
10070 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510071 CreateMockRead(stream1_body, 4, ASYNC),
10072 CreateMockRead(stream2_body, 5, ASYNC),
10073 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:2910074 };
10075
Ryan Sleevib8d7ea02018-05-07 20:01:0110076 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710077 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:2910078 // Negotiate SPDY to the proxy
10079 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610080 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710081 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:2910082
bnc87dcefc2017-05-25 12:47:5810083 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910084 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:2910085 TestCompletionCallback callback;
10086 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110087 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910088
10089 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110090 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910091 const HttpResponseInfo* response = trans->GetResponseInfo();
10092
bnc87dcefc2017-05-25 12:47:5810093 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:1910094 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:5010095 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110096 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910097
10098 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110099 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910100 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
10101
wezca1070932016-05-26 20:30:5210102 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:2910103 EXPECT_TRUE(response->headers->IsKeepAlive());
10104
10105 EXPECT_EQ(200, response->headers->response_code());
10106 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10107
10108 std::string response_data;
10109 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110110 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910111 EXPECT_EQ("hello!", response_data);
10112
[email protected]029c83b62013-01-24 05:28:2010113 LoadTimingInfo load_timing_info;
10114 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10115 TestLoadTimingNotReusedWithPac(load_timing_info,
10116 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10117
[email protected]7c6f7ba2012-04-03 04:09:2910118 // Verify the pushed stream.
wezca1070932016-05-26 20:30:5210119 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:2910120 EXPECT_EQ(200, push_response->headers->response_code());
10121
10122 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110123 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910124 EXPECT_EQ("pushed", response_data);
10125
[email protected]029c83b62013-01-24 05:28:2010126 LoadTimingInfo push_load_timing_info;
10127 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
10128 TestLoadTimingReusedWithPac(push_load_timing_info);
10129 // The transactions should share a socket ID, despite being for different
10130 // origins.
10131 EXPECT_EQ(load_timing_info.socket_log_id,
10132 push_load_timing_info.socket_log_id);
10133
[email protected]7c6f7ba2012-04-03 04:09:2910134 trans.reset();
10135 push_trans.reset();
10136 session->CloseAllConnections();
10137}
10138
[email protected]8c843192012-04-05 07:15:0010139// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:0110140TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510141 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910142 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510143 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10144 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:0010145 HttpRequestInfo request;
10146
10147 request.method = "GET";
bncce36dca22015-04-21 22:11:2310148 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010149 request.traffic_annotation =
10150 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:0010151
Ramin Halavatica8d5252018-03-12 05:33:4910152 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10153 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110154 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710155 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010156
10157 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210158 session_deps_.proxy_resolution_service->SetProxyDelegate(
10159 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010160
danakj1fd259a02016-04-16 03:17:0910161 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:0010162
Ryan Hamilton0239aac2018-05-19 00:03:1310163 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510164 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:0010165
Ryan Hamilton0239aac2018-05-19 00:03:1310166 spdy::SpdySerializedFrame push_rst(
10167 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:0010168
10169 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110170 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:0010171 };
10172
Ryan Hamilton0239aac2018-05-19 00:03:1310173 spdy::SpdySerializedFrame stream1_reply(
Raul Tambre94493c652019-03-11 17:18:3510174 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]8c843192012-04-05 07:15:0010175
Ryan Hamilton0239aac2018-05-19 00:03:1310176 spdy::SpdySerializedFrame stream1_body(
10177 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:0010178
Ryan Hamilton0239aac2018-05-19 00:03:1310179 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Raul Tambre94493c652019-03-11 17:18:3510180 nullptr, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:0010181
10182 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110183 CreateMockRead(stream1_reply, 1, ASYNC),
10184 CreateMockRead(stream2_syn, 2, ASYNC),
10185 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:5910186 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:0010187 };
10188
Ryan Sleevib8d7ea02018-05-07 20:01:0110189 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710190 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:0010191 // Negotiate SPDY to the proxy
10192 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610193 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710194 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:0010195
bnc87dcefc2017-05-25 12:47:5810196 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910197 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:0010198 TestCompletionCallback callback;
10199 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110200 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:0010201
10202 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110203 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010204 const HttpResponseInfo* response = trans->GetResponseInfo();
10205
wezca1070932016-05-26 20:30:5210206 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:0010207 EXPECT_TRUE(response->headers->IsKeepAlive());
10208
10209 EXPECT_EQ(200, response->headers->response_code());
10210 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10211
10212 std::string response_data;
10213 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110214 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010215 EXPECT_EQ("hello!", response_data);
10216
10217 trans.reset();
10218 session->CloseAllConnections();
10219}
10220
tbansal8ef1d3e2016-02-03 04:05:4210221// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
10222// resources.
bncd16676a2016-07-20 16:23:0110223TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510224 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910225 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510226 proxy_delegate->set_trusted_spdy_proxy(
10227 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
10228
tbansal8ef1d3e2016-02-03 04:05:4210229 HttpRequestInfo request;
10230
10231 request.method = "GET";
10232 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010233 request.traffic_annotation =
10234 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210235
10236 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:4910237 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10238 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210239 BoundTestNetLog log;
10240 session_deps_.net_log = log.bound().net_log();
10241
10242 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210243 session_deps_.proxy_resolution_service->SetProxyDelegate(
10244 proxy_delegate.get());
tbansal8ef1d3e2016-02-03 04:05:4210245
danakj1fd259a02016-04-16 03:17:0910246 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:4210247
Ryan Hamilton0239aac2018-05-19 00:03:1310248 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510249 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310250 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510251 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:4210252
10253 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110254 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510255 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:4210256 };
10257
Ryan Hamilton0239aac2018-05-19 00:03:1310258 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:1510259 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210260
Ryan Hamilton0239aac2018-05-19 00:03:1310261 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:3310262 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:4910263
Ryan Hamilton0239aac2018-05-19 00:03:1310264 spdy::SpdySerializedFrame stream1_body(
10265 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210266
Ryan Hamilton0239aac2018-05-19 00:03:1310267 spdy::SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:1510268 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210269
Ryan Hamilton0239aac2018-05-19 00:03:1310270 spdy::SpdySerializedFrame stream2_body(
10271 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210272
10273 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110274 CreateMockRead(stream1_reply, 1, ASYNC),
10275 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510276 CreateMockRead(stream1_body, 4, ASYNC),
10277 CreateMockRead(stream2_body, 5, ASYNC),
10278 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:4210279 };
10280
Ryan Sleevib8d7ea02018-05-07 20:01:0110281 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
tbansal8ef1d3e2016-02-03 04:05:4210282 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10283 // Negotiate SPDY to the proxy
10284 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610285 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:4210286 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
10287
bnc87dcefc2017-05-25 12:47:5810288 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910289 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:4210290 TestCompletionCallback callback;
10291 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110292 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:4210293
10294 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110295 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210296 const HttpResponseInfo* response = trans->GetResponseInfo();
10297
wezca1070932016-05-26 20:30:5210298 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:4210299 EXPECT_TRUE(response->headers->IsKeepAlive());
10300
10301 EXPECT_EQ(200, response->headers->response_code());
10302 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10303
10304 std::string response_data;
10305 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110306 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210307 EXPECT_EQ("hello!", response_data);
10308
10309 trans.reset();
10310 session->CloseAllConnections();
10311}
10312
[email protected]2df19bb2010-08-25 20:13:4610313// Test HTTPS connections to a site with a bad certificate, going through an
10314// HTTPS proxy
bncd16676a2016-07-20 16:23:0110315TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:4910316 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10317 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610318
10319 HttpRequestInfo request;
10320 request.method = "GET";
bncce36dca22015-04-21 22:11:2310321 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010322 request.traffic_annotation =
10323 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610324
10325 // Attempt to fetch the URL from a server with a bad cert
10326 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710327 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10328 "Host: www.example.org:443\r\n"
10329 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610330 };
10331
10332 MockRead bad_cert_reads[] = {
10333 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610334 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:4610335 };
10336
10337 // Attempt to fetch the URL with a good cert
10338 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710339 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10340 "Host: www.example.org:443\r\n"
10341 "Proxy-Connection: keep-alive\r\n\r\n"),
10342 MockWrite("GET / HTTP/1.1\r\n"
10343 "Host: www.example.org\r\n"
10344 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610345 };
10346
10347 MockRead good_cert_reads[] = {
10348 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
10349 MockRead("HTTP/1.0 200 OK\r\n"),
10350 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10351 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610352 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:4610353 };
10354
Ryan Sleevib8d7ea02018-05-07 20:01:0110355 StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
10356 StaticSocketDataProvider data(good_cert_reads, good_data_writes);
[email protected]8ddf8322012-02-23 18:08:0610357 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
10358 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:4610359
10360 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:0710361 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10362 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
10363 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:4610364
10365 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:0710366 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10367 session_deps_.socket_factory->AddSocketDataProvider(&data);
10368 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:4610369
[email protected]49639fa2011-12-20 23:22:4110370 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:4610371
danakj1fd259a02016-04-16 03:17:0910372 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610373 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:4610374
tfarina42834112016-09-22 13:38:2010375 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110376 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610377
10378 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110379 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:4610380
bnc691fda62016-08-12 00:43:1610381 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:0110382 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610383
10384 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110385 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:4610386
bnc691fda62016-08-12 00:43:1610387 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:4610388
wezca1070932016-05-26 20:30:5210389 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:4610390 EXPECT_EQ(100, response->headers->GetContentLength());
10391}
10392
bncd16676a2016-07-20 16:23:0110393TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:4210394 HttpRequestInfo request;
10395 request.method = "GET";
bncce36dca22015-04-21 22:11:2310396 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310397 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10398 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:1010399 request.traffic_annotation =
10400 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210401
danakj1fd259a02016-04-16 03:17:0910402 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610403 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710404
[email protected]1c773ea12009-04-28 19:58:4210405 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310406 MockWrite(
10407 "GET / HTTP/1.1\r\n"
10408 "Host: www.example.org\r\n"
10409 "Connection: keep-alive\r\n"
10410 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210411 };
10412
10413 // Lastly, the server responds with the actual content.
10414 MockRead data_reads[] = {
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]1c773ea12009-04-28 19:58:4210419 };
10420
Ryan Sleevib8d7ea02018-05-07 20:01:0110421 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710422 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210423
[email protected]49639fa2011-12-20 23:22:4110424 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210425
tfarina42834112016-09-22 13:38:2010426 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110427 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210428
10429 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110430 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210431}
10432
bncd16676a2016-07-20 16:23:0110433TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
Matt Menked732ea42019-03-08 12:05:0010434 // Test user agent values, used both for the request header of the original
10435 // request, and the value returned by the HttpUserAgentSettings. nullptr means
10436 // no request header / no HttpUserAgentSettings object.
10437 const char* kTestUserAgents[] = {nullptr, "", "Foopy"};
[email protected]da81f132010-08-18 23:39:2910438
Matt Menked732ea42019-03-08 12:05:0010439 for (const char* setting_user_agent : kTestUserAgents) {
10440 if (!setting_user_agent) {
10441 session_deps_.http_user_agent_settings.reset();
10442 } else {
10443 session_deps_.http_user_agent_settings =
10444 std::make_unique<StaticHttpUserAgentSettings>(
10445 std::string() /* accept-language */, setting_user_agent);
10446 }
10447 session_deps_.proxy_resolution_service =
10448 ProxyResolutionService::CreateFixed("myproxy:70",
10449 TRAFFIC_ANNOTATION_FOR_TESTS);
10450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10451 for (const char* request_user_agent : kTestUserAgents) {
10452 HttpRequestInfo request;
10453 request.method = "GET";
10454 request.url = GURL("https://www.example.org/");
10455 if (request_user_agent) {
10456 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10457 request_user_agent);
10458 }
10459 request.traffic_annotation =
10460 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710461
Matt Menked732ea42019-03-08 12:05:0010462 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]da81f132010-08-18 23:39:2910463
Matt Menked732ea42019-03-08 12:05:0010464 std::string expected_request;
10465 if (!setting_user_agent || strlen(setting_user_agent) == 0) {
10466 expected_request =
10467 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10468 "Host: www.example.org:443\r\n"
10469 "Proxy-Connection: keep-alive\r\n\r\n";
10470 } else {
10471 expected_request = base::StringPrintf(
10472 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10473 "Host: www.example.org:443\r\n"
10474 "Proxy-Connection: keep-alive\r\n"
10475 "User-Agent: %s\r\n\r\n",
10476 setting_user_agent);
10477 }
10478 MockWrite data_writes[] = {
10479 MockWrite(expected_request.c_str()),
10480 };
10481 MockRead data_reads[] = {
10482 // Return an error, so the transaction stops here (this test isn't
10483 // interested in the rest).
10484 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
10485 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10486 MockRead("Proxy-Connection: close\r\n\r\n"),
10487 };
[email protected]da81f132010-08-18 23:39:2910488
Matt Menked732ea42019-03-08 12:05:0010489 StaticSocketDataProvider data(data_reads, data_writes);
10490 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:2910491
Matt Menked732ea42019-03-08 12:05:0010492 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:2910493
Matt Menked732ea42019-03-08 12:05:0010494 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10495 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10496
10497 rv = callback.WaitForResult();
10498 EXPECT_THAT(rv, IsOk());
10499 }
10500 }
[email protected]da81f132010-08-18 23:39:2910501}
10502
bncd16676a2016-07-20 16:23:0110503TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:4210504 HttpRequestInfo request;
10505 request.method = "GET";
bncce36dca22015-04-21 22:11:2310506 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:1610507 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
10508 "http://the.previous.site.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010509 request.traffic_annotation =
10510 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210511
danakj1fd259a02016-04-16 03:17:0910512 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610513 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710514
[email protected]1c773ea12009-04-28 19:58:4210515 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310516 MockWrite(
10517 "GET / HTTP/1.1\r\n"
10518 "Host: www.example.org\r\n"
10519 "Connection: keep-alive\r\n"
10520 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210521 };
10522
10523 // Lastly, the server responds with the actual content.
10524 MockRead data_reads[] = {
10525 MockRead("HTTP/1.0 200 OK\r\n"),
10526 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10527 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610528 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210529 };
10530
Ryan Sleevib8d7ea02018-05-07 20:01:0110531 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710532 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210533
[email protected]49639fa2011-12-20 23:22:4110534 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210535
tfarina42834112016-09-22 13:38:2010536 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110537 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210538
10539 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110540 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210541}
10542
bncd16676a2016-07-20 16:23:0110543TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210544 HttpRequestInfo request;
10545 request.method = "POST";
bncce36dca22015-04-21 22:11:2310546 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010547 request.traffic_annotation =
10548 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210549
danakj1fd259a02016-04-16 03:17:0910550 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610551 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710552
[email protected]1c773ea12009-04-28 19:58:4210553 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310554 MockWrite(
10555 "POST / HTTP/1.1\r\n"
10556 "Host: www.example.org\r\n"
10557 "Connection: keep-alive\r\n"
10558 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210559 };
10560
10561 // Lastly, the server responds with the actual content.
10562 MockRead data_reads[] = {
10563 MockRead("HTTP/1.0 200 OK\r\n"),
10564 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10565 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610566 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210567 };
10568
Ryan Sleevib8d7ea02018-05-07 20:01:0110569 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710570 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210571
[email protected]49639fa2011-12-20 23:22:4110572 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210573
tfarina42834112016-09-22 13:38:2010574 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110575 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210576
10577 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110578 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210579}
10580
bncd16676a2016-07-20 16:23:0110581TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210582 HttpRequestInfo request;
10583 request.method = "PUT";
bncce36dca22015-04-21 22:11:2310584 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010585 request.traffic_annotation =
10586 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210587
danakj1fd259a02016-04-16 03:17:0910588 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610589 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710590
[email protected]1c773ea12009-04-28 19:58:4210591 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310592 MockWrite(
10593 "PUT / HTTP/1.1\r\n"
10594 "Host: www.example.org\r\n"
10595 "Connection: keep-alive\r\n"
10596 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210597 };
10598
10599 // Lastly, the server responds with the actual content.
10600 MockRead data_reads[] = {
10601 MockRead("HTTP/1.0 200 OK\r\n"),
10602 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10603 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610604 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210605 };
10606
Ryan Sleevib8d7ea02018-05-07 20:01:0110607 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710608 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210609
[email protected]49639fa2011-12-20 23:22:4110610 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210611
tfarina42834112016-09-22 13:38:2010612 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110613 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210614
10615 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110616 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210617}
10618
bncd16676a2016-07-20 16:23:0110619TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210620 HttpRequestInfo request;
10621 request.method = "HEAD";
bncce36dca22015-04-21 22:11:2310622 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010623 request.traffic_annotation =
10624 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210625
danakj1fd259a02016-04-16 03:17:0910626 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610627 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710628
[email protected]1c773ea12009-04-28 19:58:4210629 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:1310630 MockWrite("HEAD / HTTP/1.1\r\n"
10631 "Host: www.example.org\r\n"
10632 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210633 };
10634
10635 // Lastly, the server responds with the actual content.
10636 MockRead data_reads[] = {
10637 MockRead("HTTP/1.0 200 OK\r\n"),
10638 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10639 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610640 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210641 };
10642
Ryan Sleevib8d7ea02018-05-07 20:01:0110643 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710644 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210645
[email protected]49639fa2011-12-20 23:22:4110646 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210647
tfarina42834112016-09-22 13:38:2010648 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110649 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210650
10651 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110652 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210653}
10654
bncd16676a2016-07-20 16:23:0110655TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:4210656 HttpRequestInfo request;
10657 request.method = "GET";
bncce36dca22015-04-21 22:11:2310658 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210659 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:1010660 request.traffic_annotation =
10661 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210662
danakj1fd259a02016-04-16 03:17:0910663 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610664 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710665
[email protected]1c773ea12009-04-28 19:58:4210666 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310667 MockWrite(
10668 "GET / HTTP/1.1\r\n"
10669 "Host: www.example.org\r\n"
10670 "Connection: keep-alive\r\n"
10671 "Pragma: no-cache\r\n"
10672 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210673 };
10674
10675 // Lastly, the server responds with the actual content.
10676 MockRead data_reads[] = {
10677 MockRead("HTTP/1.0 200 OK\r\n"),
10678 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10679 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610680 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210681 };
10682
Ryan Sleevib8d7ea02018-05-07 20:01:0110683 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710684 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210685
[email protected]49639fa2011-12-20 23:22:4110686 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210687
tfarina42834112016-09-22 13:38:2010688 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110689 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210690
10691 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110692 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210693}
10694
bncd16676a2016-07-20 16:23:0110695TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:4210696 HttpRequestInfo request;
10697 request.method = "GET";
bncce36dca22015-04-21 22:11:2310698 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210699 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:1010700 request.traffic_annotation =
10701 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210702
danakj1fd259a02016-04-16 03:17:0910703 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610704 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710705
[email protected]1c773ea12009-04-28 19:58:4210706 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310707 MockWrite(
10708 "GET / HTTP/1.1\r\n"
10709 "Host: www.example.org\r\n"
10710 "Connection: keep-alive\r\n"
10711 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210712 };
10713
10714 // Lastly, the server responds with the actual content.
10715 MockRead data_reads[] = {
10716 MockRead("HTTP/1.0 200 OK\r\n"),
10717 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10718 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610719 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210720 };
10721
Ryan Sleevib8d7ea02018-05-07 20:01:0110722 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710723 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210724
[email protected]49639fa2011-12-20 23:22:4110725 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210726
tfarina42834112016-09-22 13:38:2010727 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110728 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210729
10730 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110731 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210732}
10733
bncd16676a2016-07-20 16:23:0110734TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:4210735 HttpRequestInfo request;
10736 request.method = "GET";
bncce36dca22015-04-21 22:11:2310737 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310738 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e62018-02-07 07:41:1010739 request.traffic_annotation =
10740 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210741
danakj1fd259a02016-04-16 03:17:0910742 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610743 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710744
[email protected]1c773ea12009-04-28 19:58:4210745 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310746 MockWrite(
10747 "GET / HTTP/1.1\r\n"
10748 "Host: www.example.org\r\n"
10749 "Connection: keep-alive\r\n"
10750 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210751 };
10752
10753 // Lastly, the server responds with the actual content.
10754 MockRead data_reads[] = {
10755 MockRead("HTTP/1.0 200 OK\r\n"),
10756 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10757 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610758 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210759 };
10760
Ryan Sleevib8d7ea02018-05-07 20:01:0110761 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710762 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210763
[email protected]49639fa2011-12-20 23:22:4110764 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210765
tfarina42834112016-09-22 13:38:2010766 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110767 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210768
10769 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110770 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210771}
10772
bncd16676a2016-07-20 16:23:0110773TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:4710774 HttpRequestInfo request;
10775 request.method = "GET";
bncce36dca22015-04-21 22:11:2310776 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310777 request.extra_headers.SetHeader("referer", "www.foo.com");
10778 request.extra_headers.SetHeader("hEllo", "Kitty");
10779 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:1010780 request.traffic_annotation =
10781 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:4710782
danakj1fd259a02016-04-16 03:17:0910783 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610784 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710785
[email protected]270c6412010-03-29 22:02:4710786 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310787 MockWrite(
10788 "GET / HTTP/1.1\r\n"
10789 "Host: www.example.org\r\n"
10790 "Connection: keep-alive\r\n"
10791 "referer: www.foo.com\r\n"
10792 "hEllo: Kitty\r\n"
10793 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:4710794 };
10795
10796 // Lastly, the server responds with the actual content.
10797 MockRead data_reads[] = {
10798 MockRead("HTTP/1.0 200 OK\r\n"),
10799 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10800 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610801 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:4710802 };
10803
Ryan Sleevib8d7ea02018-05-07 20:01:0110804 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710805 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:4710806
[email protected]49639fa2011-12-20 23:22:4110807 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:4710808
tfarina42834112016-09-22 13:38:2010809 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110810 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:4710811
10812 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110813 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:4710814}
10815
bncd16676a2016-07-20 16:23:0110816TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710817 HttpRequestInfo request;
10818 request.method = "GET";
bncce36dca22015-04-21 22:11:2310819 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010820 request.traffic_annotation =
10821 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710822
Lily Houghton8c2f97d2018-01-22 05:06:5910823 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910824 ProxyResolutionService::CreateFixedFromPacResult(
10825 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110826 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710827 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210828
danakj1fd259a02016-04-16 03:17:0910829 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610830 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210831
[email protected]3cd17242009-06-23 02:59:0210832 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10833 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10834
10835 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410836 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10837 MockWrite("GET / HTTP/1.1\r\n"
10838 "Host: www.example.org\r\n"
10839 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210840
10841 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410842 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10843 MockRead("HTTP/1.0 200 OK\r\n"),
10844 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10845 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0210846
Ryan Sleevib8d7ea02018-05-07 20:01:0110847 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710848 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210849
[email protected]49639fa2011-12-20 23:22:4110850 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210851
tfarina42834112016-09-22 13:38:2010852 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110853 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210854
10855 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110856 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210857
bnc691fda62016-08-12 00:43:1610858 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210859 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:0210860
tbansal2ecbbc72016-10-06 17:15:4710861 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:2010862 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610863 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010864 TestLoadTimingNotReusedWithPac(load_timing_info,
10865 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10866
[email protected]3cd17242009-06-23 02:59:0210867 std::string response_text;
bnc691fda62016-08-12 00:43:1610868 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110869 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210870 EXPECT_EQ("Payload", response_text);
10871}
10872
bncd16676a2016-07-20 16:23:0110873TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710874 HttpRequestInfo request;
10875 request.method = "GET";
bncce36dca22015-04-21 22:11:2310876 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010877 request.traffic_annotation =
10878 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710879
Lily Houghton8c2f97d2018-01-22 05:06:5910880 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910881 ProxyResolutionService::CreateFixedFromPacResult(
10882 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110883 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710884 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210885
danakj1fd259a02016-04-16 03:17:0910886 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610887 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210888
[email protected]3cd17242009-06-23 02:59:0210889 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
10890 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10891
10892 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310893 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
Avi Drissman4365a4782018-12-28 19:26:2410894 base::size(write_buffer)),
10895 MockWrite("GET / HTTP/1.1\r\n"
10896 "Host: www.example.org\r\n"
10897 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210898
10899 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410900 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
10901 base::size(read_buffer)),
10902 MockRead("HTTP/1.0 200 OK\r\n"),
10903 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10904 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3510905
Ryan Sleevib8d7ea02018-05-07 20:01:0110906 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710907 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510908
[email protected]8ddf8322012-02-23 18:08:0610909 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710910 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:3510911
[email protected]49639fa2011-12-20 23:22:4110912 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510913
tfarina42834112016-09-22 13:38:2010914 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110915 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510916
10917 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110918 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510919
[email protected]029c83b62013-01-24 05:28:2010920 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610921 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010922 TestLoadTimingNotReusedWithPac(load_timing_info,
10923 CONNECT_TIMING_HAS_SSL_TIMES);
10924
bnc691fda62016-08-12 00:43:1610925 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210926 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710927 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510928
10929 std::string response_text;
bnc691fda62016-08-12 00:43:1610930 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110931 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510932 EXPECT_EQ("Payload", response_text);
10933}
10934
bncd16676a2016-07-20 16:23:0110935TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:2010936 HttpRequestInfo request;
10937 request.method = "GET";
bncce36dca22015-04-21 22:11:2310938 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010939 request.traffic_annotation =
10940 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:2010941
Ramin Halavatica8d5252018-03-12 05:33:4910942 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10943 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110944 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710945 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:2010946
danakj1fd259a02016-04-16 03:17:0910947 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610948 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:2010949
10950 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10951 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10952
10953 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410954 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10955 MockWrite("GET / HTTP/1.1\r\n"
10956 "Host: www.example.org\r\n"
10957 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:2010958
10959 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410960 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10961 MockRead("HTTP/1.0 200 OK\r\n"),
10962 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10963 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]029c83b62013-01-24 05:28:2010964
Ryan Sleevib8d7ea02018-05-07 20:01:0110965 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710966 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:2010967
10968 TestCompletionCallback callback;
10969
tfarina42834112016-09-22 13:38:2010970 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110971 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:2010972
10973 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110974 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010975
bnc691fda62016-08-12 00:43:1610976 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210977 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:2010978
10979 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610980 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010981 TestLoadTimingNotReused(load_timing_info,
10982 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10983
10984 std::string response_text;
bnc691fda62016-08-12 00:43:1610985 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110986 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010987 EXPECT_EQ("Payload", response_text);
10988}
10989
bncd16676a2016-07-20 16:23:0110990TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710991 HttpRequestInfo request;
10992 request.method = "GET";
bncce36dca22015-04-21 22:11:2310993 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010994 request.traffic_annotation =
10995 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710996
Lily Houghton8c2f97d2018-01-22 05:06:5910997 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910998 ProxyResolutionService::CreateFixedFromPacResult(
10999 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111000 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711001 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3511002
danakj1fd259a02016-04-16 03:17:0911003 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611004 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3511005
[email protected]e0c27be2009-07-15 13:09:3511006 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
11007 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3711008 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2311009 0x05, // Version
11010 0x01, // Command (CONNECT)
11011 0x00, // Reserved.
11012 0x03, // Address type (DOMAINNAME).
11013 0x0F, // Length of domain (15)
11014 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
11015 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3711016 };
[email protected]e0c27be2009-07-15 13:09:3511017 const char kSOCKS5OkResponse[] =
11018 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
11019
11020 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411021 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
11022 MockWrite(ASYNC, kSOCKS5OkRequest, base::size(kSOCKS5OkRequest)),
11023 MockWrite("GET / HTTP/1.1\r\n"
11024 "Host: www.example.org\r\n"
11025 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3511026
11027 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411028 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11029 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11030 MockRead("HTTP/1.0 200 OK\r\n"),
11031 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11032 MockRead("Payload"),
11033 MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3511034
Ryan Sleevib8d7ea02018-05-07 20:01:0111035 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711036 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3511037
[email protected]49639fa2011-12-20 23:22:4111038 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3511039
tfarina42834112016-09-22 13:38:2011040 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111041 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3511042
11043 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111044 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3511045
bnc691fda62016-08-12 00:43:1611046 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211047 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711048 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3511049
[email protected]029c83b62013-01-24 05:28:2011050 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611051 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011052 TestLoadTimingNotReusedWithPac(load_timing_info,
11053 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
11054
[email protected]e0c27be2009-07-15 13:09:3511055 std::string response_text;
bnc691fda62016-08-12 00:43:1611056 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111057 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3511058 EXPECT_EQ("Payload", response_text);
11059}
11060
bncd16676a2016-07-20 16:23:0111061TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2711062 HttpRequestInfo request;
11063 request.method = "GET";
bncce36dca22015-04-21 22:11:2311064 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011065 request.traffic_annotation =
11066 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711067
Lily Houghton8c2f97d2018-01-22 05:06:5911068 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911069 ProxyResolutionService::CreateFixedFromPacResult(
11070 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111071 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711072 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3511073
danakj1fd259a02016-04-16 03:17:0911074 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611075 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3511076
[email protected]e0c27be2009-07-15 13:09:3511077 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
11078 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3711079 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2311080 0x05, // Version
11081 0x01, // Command (CONNECT)
11082 0x00, // Reserved.
11083 0x03, // Address type (DOMAINNAME).
11084 0x0F, // Length of domain (15)
11085 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
11086 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3711087 };
11088
[email protected]e0c27be2009-07-15 13:09:3511089 const char kSOCKS5OkResponse[] =
11090 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
11091
11092 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411093 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
bncce36dca22015-04-21 22:11:2311094 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
Avi Drissman4365a4782018-12-28 19:26:2411095 base::size(kSOCKS5OkRequest)),
11096 MockWrite("GET / HTTP/1.1\r\n"
11097 "Host: www.example.org\r\n"
11098 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3511099
11100 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411101 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11102 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11103 MockRead("HTTP/1.0 200 OK\r\n"),
11104 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11105 MockRead("Payload"),
11106 MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0211107
Ryan Sleevib8d7ea02018-05-07 20:01:0111108 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711109 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0211110
[email protected]8ddf8322012-02-23 18:08:0611111 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711112 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0211113
[email protected]49639fa2011-12-20 23:22:4111114 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0211115
tfarina42834112016-09-22 13:38:2011116 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111117 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0211118
11119 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111120 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211121
bnc691fda62016-08-12 00:43:1611122 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211123 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711124 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0211125
[email protected]029c83b62013-01-24 05:28:2011126 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611127 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011128 TestLoadTimingNotReusedWithPac(load_timing_info,
11129 CONNECT_TIMING_HAS_SSL_TIMES);
11130
[email protected]3cd17242009-06-23 02:59:0211131 std::string response_text;
bnc691fda62016-08-12 00:43:1611132 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111133 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211134 EXPECT_EQ("Payload", response_text);
11135}
11136
[email protected]448d4ca52012-03-04 04:12:2311137namespace {
11138
Matt Menkef6edce752019-03-19 17:21:5611139// Tests that for connection endpoints the group ids are correctly set.
[email protected]2d731a32010-04-29 01:04:0611140
Matt Menkef6edce752019-03-19 17:21:5611141struct GroupIdTest {
[email protected]2d731a32010-04-29 01:04:0611142 std::string proxy_server;
11143 std::string url;
Matt Menkef6edce752019-03-19 17:21:5611144 ClientSocketPool::GroupId expected_group_id;
[email protected]e60e47a2010-07-14 03:37:1811145 bool ssl;
[email protected]2d731a32010-04-29 01:04:0611146};
11147
Matt Menkef6edce752019-03-19 17:21:5611148std::unique_ptr<HttpNetworkSession> SetupSessionForGroupIdTests(
[email protected]bb88e1d32013-05-03 23:11:0711149 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0911150 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0611151
bnc525e175a2016-06-20 12:36:4011152 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311153 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111154 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1211155 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111156 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4211157 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4611158 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0611159
11160 return session;
11161}
11162
Matt Menkef6edce752019-03-19 17:21:5611163int GroupIdTransactionHelper(const std::string& url,
11164 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0611165 HttpRequestInfo request;
11166 request.method = "GET";
11167 request.url = GURL(url);
Ramin Halavatib5e433e62018-02-07 07:41:1011168 request.traffic_annotation =
11169 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0611170
bnc691fda62016-08-12 00:43:1611171 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2711172
[email protected]49639fa2011-12-20 23:22:4111173 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0611174
11175 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2011176 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0611177}
11178
[email protected]448d4ca52012-03-04 04:12:2311179} // namespace
11180
Matt Menkef6edce752019-03-19 17:21:5611181TEST_F(HttpNetworkTransactionTest, GroupIdForDirectConnections) {
11182 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311183 {
Matt Menkef6edce752019-03-19 17:21:5611184 "", // unused
11185 "http://www.example.org/direct",
11186 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11187 ClientSocketPool::SocketType::kHttp,
11188 false /* privacy_mode */),
11189 false,
bncce36dca22015-04-21 22:11:2311190 },
11191 {
Matt Menkef6edce752019-03-19 17:21:5611192 "", // unused
11193 "http://[2001:1418:13:1::25]/direct",
11194 ClientSocketPool::GroupId(HostPortPair("2001:1418:13:1::25", 80),
11195 ClientSocketPool::SocketType::kHttp,
11196 false /* privacy_mode */),
11197 false,
bncce36dca22015-04-21 22:11:2311198 },
[email protected]04e5be32009-06-26 20:00:3111199
bncce36dca22015-04-21 22:11:2311200 // SSL Tests
11201 {
Matt Menkef6edce752019-03-19 17:21:5611202 "", // unused
11203 "https://www.example.org/direct_ssl",
11204 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11205 ClientSocketPool::SocketType::kSsl,
11206 false /* privacy_mode */),
11207 true,
bncce36dca22015-04-21 22:11:2311208 },
11209 {
Matt Menkef6edce752019-03-19 17:21:5611210 "", // unused
11211 "https://[2001:1418:13:1::25]/direct",
11212 ClientSocketPool::GroupId(HostPortPair("2001:1418:13:1::25", 443),
11213 ClientSocketPool::SocketType::kSsl,
11214 false /* privacy_mode */),
11215 true,
bncce36dca22015-04-21 22:11:2311216 },
11217 {
Matt Menkef6edce752019-03-19 17:21:5611218 "", // unused
11219 "https://host.with.alternate/direct",
11220 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11221 ClientSocketPool::SocketType::kSsl,
11222 false /* privacy_mode */),
11223 true,
bncce36dca22015-04-21 22:11:2311224 },
[email protected]2d731a32010-04-29 01:04:0611225 };
[email protected]2ff8b312010-04-26 22:20:5411226
Avi Drissman4365a4782018-12-28 19:26:2411227 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911228 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911229 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11230 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911231 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611232 SetupSessionForGroupIdTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611233
mmenkee65e7af2015-10-13 17:16:4211234 HttpNetworkSessionPeer peer(session.get());
Matt Menkef6edce752019-03-19 17:21:5611235 CaptureGroupIdTransportSocketPool* transport_conn_pool =
Matt Menked6fd2a52019-03-20 06:14:3611236 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911237 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011238 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
11239 base::WrapUnique(transport_conn_pool));
dchengc7eeda422015-12-26 03:56:4811240 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611241
11242 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611243 GroupIdTransactionHelper(tests[i].url, session.get()));
11244 EXPECT_EQ(tests[i].expected_group_id,
11245 transport_conn_pool->last_group_id_received());
Matt Menke9d5e2c92019-02-05 01:42:2311246 EXPECT_TRUE(transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0611247 }
[email protected]2d731a32010-04-29 01:04:0611248}
11249
Matt Menkef6edce752019-03-19 17:21:5611250TEST_F(HttpNetworkTransactionTest, GroupIdForHTTPProxyConnections) {
11251 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311252 {
Matt Menke4802de62019-03-08 22:47:5011253 "http_proxy",
11254 "http://www.example.org/http_proxy_normal",
Matt Menkef6edce752019-03-19 17:21:5611255 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11256 ClientSocketPool::SocketType::kHttp,
11257 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011258 false,
bncce36dca22015-04-21 22:11:2311259 },
[email protected]2d731a32010-04-29 01:04:0611260
bncce36dca22015-04-21 22:11:2311261 // SSL Tests
11262 {
Matt Menke4802de62019-03-08 22:47:5011263 "http_proxy",
11264 "https://www.example.org/http_connect_ssl",
Matt Menkef6edce752019-03-19 17:21:5611265 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11266 ClientSocketPool::SocketType::kSsl,
11267 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011268 true,
bncce36dca22015-04-21 22:11:2311269 },
[email protected]af3490e2010-10-16 21:02:2911270
bncce36dca22015-04-21 22:11:2311271 {
Matt Menke4802de62019-03-08 22:47:5011272 "http_proxy",
11273 "https://host.with.alternate/direct",
Matt Menkef6edce752019-03-19 17:21:5611274 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11275 ClientSocketPool::SocketType::kSsl,
11276 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011277 true,
bncce36dca22015-04-21 22:11:2311278 },
[email protected]45499252013-01-23 17:12:5611279
bncce36dca22015-04-21 22:11:2311280 {
Matt Menke4802de62019-03-08 22:47:5011281 "http_proxy",
11282 "ftp://ftp.google.com/http_proxy_normal",
Matt Menkef6edce752019-03-19 17:21:5611283 ClientSocketPool::GroupId(HostPortPair("ftp.google.com", 21),
11284 ClientSocketPool::SocketType::kFtp,
11285 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011286 false,
bncce36dca22015-04-21 22:11:2311287 },
[email protected]2d731a32010-04-29 01:04:0611288 };
11289
Avi Drissman4365a4782018-12-28 19:26:2411290 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911291 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911292 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11293 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911294 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611295 SetupSessionForGroupIdTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611296
mmenkee65e7af2015-10-13 17:16:4211297 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0611298
Matt Menkee8648fa2019-01-17 16:47:0711299 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11300 HostPortPair("http_proxy", 80));
Matt Menkef6edce752019-03-19 17:21:5611301 CaptureGroupIdTransportSocketPool* http_proxy_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(proxy_server,
11305 base::WrapUnique(http_proxy_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 http_proxy_pool->last_group_id_received());
[email protected]2d731a32010-04-29 01:04:0611312 }
[email protected]2d731a32010-04-29 01:04:0611313}
11314
Matt Menkef6edce752019-03-19 17:21:5611315TEST_F(HttpNetworkTransactionTest, GroupIdForSOCKSConnections) {
11316 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311317 {
Matt Menke4802de62019-03-08 22:47:5011318 "socks4://socks_proxy:1080",
11319 "http://www.example.org/socks4_direct",
Matt Menkef6edce752019-03-19 17:21:5611320 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11321 ClientSocketPool::SocketType::kHttp,
11322 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011323 false,
bncce36dca22015-04-21 22:11:2311324 },
11325 {
Matt Menke4802de62019-03-08 22:47:5011326 "socks5://socks_proxy:1080",
11327 "http://www.example.org/socks5_direct",
Matt Menkef6edce752019-03-19 17:21:5611328 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11329 ClientSocketPool::SocketType::kHttp,
11330 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011331 false,
bncce36dca22015-04-21 22:11:2311332 },
[email protected]2d731a32010-04-29 01:04:0611333
bncce36dca22015-04-21 22:11:2311334 // SSL Tests
11335 {
Matt Menke4802de62019-03-08 22:47:5011336 "socks4://socks_proxy:1080",
11337 "https://www.example.org/socks4_ssl",
Matt Menkef6edce752019-03-19 17:21:5611338 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11339 ClientSocketPool::SocketType::kSsl,
11340 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011341 true,
bncce36dca22015-04-21 22:11:2311342 },
11343 {
Matt Menke4802de62019-03-08 22:47:5011344 "socks5://socks_proxy:1080",
11345 "https://www.example.org/socks5_ssl",
Matt Menkef6edce752019-03-19 17:21:5611346 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11347 ClientSocketPool::SocketType::kSsl,
11348 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011349 true,
bncce36dca22015-04-21 22:11:2311350 },
[email protected]af3490e2010-10-16 21:02:2911351
bncce36dca22015-04-21 22:11:2311352 {
Matt Menke4802de62019-03-08 22:47:5011353 "socks4://socks_proxy:1080",
11354 "https://host.with.alternate/direct",
Matt Menkef6edce752019-03-19 17:21:5611355 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11356 ClientSocketPool::SocketType::kSsl,
11357 false /* privacy_mode */),
Matt Menke4802de62019-03-08 22:47:5011358 true,
bncce36dca22015-04-21 22:11:2311359 },
[email protected]04e5be32009-06-26 20:00:3111360 };
11361
Avi Drissman4365a4782018-12-28 19:26:2411362 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911363 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911364 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11365 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911366 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611367 SetupSessionForGroupIdTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0211368
mmenkee65e7af2015-10-13 17:16:4211369 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3111370
Matt Menkee8648fa2019-01-17 16:47:0711371 ProxyServer proxy_server(
11372 ProxyServer::FromURI(tests[i].proxy_server, ProxyServer::SCHEME_HTTP));
11373 ASSERT_TRUE(proxy_server.is_valid());
Matt Menkef6edce752019-03-19 17:21:5611374 CaptureGroupIdTransportSocketPool* socks_conn_pool =
Matt Menked6fd2a52019-03-20 06:14:3611375 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911376 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011377 mock_pool_manager->SetSocketPool(proxy_server,
11378 base::WrapUnique(socks_conn_pool));
dchengc7eeda422015-12-26 03:56:4811379 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3111380
bnc691fda62016-08-12 00:43:1611381 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3111382
[email protected]2d731a32010-04-29 01:04:0611383 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611384 GroupIdTransactionHelper(tests[i].url, session.get()));
11385 EXPECT_EQ(tests[i].expected_group_id,
11386 socks_conn_pool->last_group_id_received());
[email protected]04e5be32009-06-26 20:00:3111387 }
11388}
11389
bncd16676a2016-07-20 16:23:0111390TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2711391 HttpRequestInfo request;
11392 request.method = "GET";
bncce36dca22015-04-21 22:11:2311393 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011394 request.traffic_annotation =
11395 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711396
Ramin Halavatica8d5252018-03-12 05:33:4911397 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11398 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3211399
[email protected]69719062010-01-05 20:09:2111400 // This simulates failure resolving all hostnames; that means we will fail
11401 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0711402 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3211403
danakj1fd259a02016-04-16 03:17:0911404 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611405 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2511406
[email protected]49639fa2011-12-20 23:22:4111407 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2511408
tfarina42834112016-09-22 13:38:2011409 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111410 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2511411
[email protected]9172a982009-06-06 00:30:2511412 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111413 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2511414}
11415
[email protected]0877e3d2009-10-17 22:29:5711416// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0111417TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5711418 HttpRequestInfo request;
11419 request.method = "GET";
11420 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1011421 request.traffic_annotation =
11422 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711423
11424 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0611425 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711426 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111427 StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
[email protected]bb88e1d32013-05-03 23:11:0711428 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911429 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711430
[email protected]49639fa2011-12-20 23:22:4111431 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711432
bnc691fda62016-08-12 00:43:1611433 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711434
tfarina42834112016-09-22 13:38:2011435 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111436 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711437
11438 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111439 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5911440
11441 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611442 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911443 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711444}
11445
zmo9528c9f42015-08-04 22:12:0811446// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0111447TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5711448 HttpRequestInfo request;
11449 request.method = "GET";
11450 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1011451 request.traffic_annotation =
11452 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711453
11454 MockRead data_reads[] = {
11455 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0611456 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711457 };
11458
Ryan Sleevib8d7ea02018-05-07 20:01:0111459 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711460 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911461 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711462
[email protected]49639fa2011-12-20 23:22:4111463 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711464
bnc691fda62016-08-12 00:43:1611465 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711466
tfarina42834112016-09-22 13:38:2011467 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111468 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711469
11470 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111471 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811472
bnc691fda62016-08-12 00:43:1611473 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211474 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0811475
wezca1070932016-05-26 20:30:5211476 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0811477 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11478
11479 std::string response_data;
bnc691fda62016-08-12 00:43:1611480 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111481 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811482 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5911483
11484 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611485 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911486 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711487}
11488
11489// Make sure that a dropped connection while draining the body for auth
11490// restart does the right thing.
bncd16676a2016-07-20 16:23:0111491TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5711492 HttpRequestInfo request;
11493 request.method = "GET";
bncce36dca22015-04-21 22:11:2311494 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011495 request.traffic_annotation =
11496 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711497
11498 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311499 MockWrite(
11500 "GET / HTTP/1.1\r\n"
11501 "Host: www.example.org\r\n"
11502 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711503 };
11504
11505 MockRead data_reads1[] = {
11506 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
11507 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
11508 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11509 MockRead("Content-Length: 14\r\n\r\n"),
11510 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0611511 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711512 };
11513
Ryan Sleevib8d7ea02018-05-07 20:01:0111514 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0711515 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5711516
bnc691fda62016-08-12 00:43:1611517 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5711518 // be issuing -- the final header line contains the credentials.
11519 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311520 MockWrite(
11521 "GET / HTTP/1.1\r\n"
11522 "Host: www.example.org\r\n"
11523 "Connection: keep-alive\r\n"
11524 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711525 };
11526
11527 // Lastly, the server responds with the actual content.
11528 MockRead data_reads2[] = {
11529 MockRead("HTTP/1.1 200 OK\r\n"),
11530 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11531 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611532 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711533 };
11534
Ryan Sleevib8d7ea02018-05-07 20:01:0111535 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:0711536 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0911537 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711538
[email protected]49639fa2011-12-20 23:22:4111539 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5711540
bnc691fda62016-08-12 00:43:1611541 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011542
tfarina42834112016-09-22 13:38:2011543 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111544 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711545
11546 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111547 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711548
bnc691fda62016-08-12 00:43:1611549 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211550 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811551 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]0877e3d2009-10-17 22:29:5711552
[email protected]49639fa2011-12-20 23:22:4111553 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5711554
bnc691fda62016-08-12 00:43:1611555 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0111556 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711557
11558 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111559 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711560
bnc691fda62016-08-12 00:43:1611561 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211562 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811563 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0877e3d2009-10-17 22:29:5711564 EXPECT_EQ(100, response->headers->GetContentLength());
11565}
11566
11567// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0111568TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4911569 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11570 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711571
11572 HttpRequestInfo request;
11573 request.method = "GET";
bncce36dca22015-04-21 22:11:2311574 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011575 request.traffic_annotation =
11576 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711577
11578 MockRead proxy_reads[] = {
11579 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0611580 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5711581 };
11582
Ryan Sleevib8d7ea02018-05-07 20:01:0111583 StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
[email protected]8ddf8322012-02-23 18:08:0611584 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5711585
[email protected]bb88e1d32013-05-03 23:11:0711586 session_deps_.socket_factory->AddSocketDataProvider(&data);
11587 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5711588
[email protected]49639fa2011-12-20 23:22:4111589 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711590
[email protected]bb88e1d32013-05-03 23:11:0711591 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5711592
danakj1fd259a02016-04-16 03:17:0911593 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611594 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711595
tfarina42834112016-09-22 13:38:2011596 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111597 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711598
11599 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111600 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5711601}
11602
bncd16676a2016-07-20 16:23:0111603TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4611604 HttpRequestInfo request;
11605 request.method = "GET";
bncce36dca22015-04-21 22:11:2311606 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011607 request.traffic_annotation =
11608 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4611609
danakj1fd259a02016-04-16 03:17:0911610 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611611 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2711612
[email protected]e22e1362009-11-23 21:31:1211613 MockRead data_reads[] = {
11614 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611615 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1211616 };
[email protected]9492e4a2010-02-24 00:58:4611617
Ryan Sleevib8d7ea02018-05-07 20:01:0111618 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711619 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4611620
[email protected]49639fa2011-12-20 23:22:4111621 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4611622
tfarina42834112016-09-22 13:38:2011623 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4611625
robpercival214763f2016-07-01 23:27:0111626 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4611627
bnc691fda62016-08-12 00:43:1611628 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211629 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4611630
wezca1070932016-05-26 20:30:5211631 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4611632 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11633
11634 std::string response_data;
bnc691fda62016-08-12 00:43:1611635 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111636 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1211637}
11638
bncd16676a2016-07-20 16:23:0111639TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1511640 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5211641 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1411642 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2111643 UploadFileElementReader::ScopedOverridingContentLengthForTests
11644 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3311645
danakj1fd259a02016-04-16 03:17:0911646 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911647 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411648 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0711649 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211650 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711651
11652 HttpRequestInfo request;
11653 request.method = "POST";
bncce36dca22015-04-21 22:11:2311654 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711655 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1011656 request.traffic_annotation =
11657 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711658
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]95d88ffe2010-02-04 21:25:3311661
11662 MockRead data_reads[] = {
11663 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11664 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611665 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3311666 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111667 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711668 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3311669
[email protected]49639fa2011-12-20 23:22:4111670 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3311671
tfarina42834112016-09-22 13:38:2011672 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111673 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3311674
11675 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111676 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3311677
bnc691fda62016-08-12 00:43:1611678 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211679 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3311680
maksim.sisove869bf52016-06-23 17:11:5211681 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3311682
[email protected]dd3aa792013-07-16 19:10:2311683 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3311684}
11685
bncd16676a2016-07-20 16:23:0111686TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1511687 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5211688 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3611689 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4811690 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
11691 base::WriteFile(temp_file, temp_file_content.c_str(),
11692 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1111693 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3611694
danakj1fd259a02016-04-16 03:17:0911695 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911696 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411697 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0711698 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211699 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711700
11701 HttpRequestInfo request;
11702 request.method = "POST";
bncce36dca22015-04-21 22:11:2311703 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711704 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1011705 request.traffic_annotation =
11706 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711707
[email protected]999dd8c2013-11-12 06:45:5411708 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0911709 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611710 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3611711
Ryan Sleevib8d7ea02018-05-07 20:01:0111712 StaticSocketDataProvider data;
[email protected]bb88e1d32013-05-03 23:11:0711713 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3611714
[email protected]49639fa2011-12-20 23:22:4111715 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3611716
tfarina42834112016-09-22 13:38:2011717 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3611719
11720 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111721 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3611722
[email protected]dd3aa792013-07-16 19:10:2311723 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3611724}
11725
bncd16676a2016-07-20 16:23:0111726TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0311727 class FakeUploadElementReader : public UploadElementReader {
11728 public:
Chris Watkins7a41d3552017-12-01 02:13:2711729 FakeUploadElementReader() = default;
11730 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0311731
Matt Menkecc1d3a902018-02-05 18:27:3311732 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0311733
11734 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3311735 int Init(CompletionOnceCallback callback) override {
11736 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0311737 return ERR_IO_PENDING;
11738 }
avibf0746c2015-12-09 19:53:1411739 uint64_t GetContentLength() const override { return 0; }
11740 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2011741 int Read(IOBuffer* buf,
11742 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3311743 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0311744 return ERR_FAILED;
11745 }
11746
11747 private:
Matt Menkecc1d3a902018-02-05 18:27:3311748 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0311749 };
11750
11751 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0911752 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11753 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2211754 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0311755
11756 HttpRequestInfo request;
11757 request.method = "POST";
bncce36dca22015-04-21 22:11:2311758 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0311759 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1011760 request.traffic_annotation =
11761 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0311762
danakj1fd259a02016-04-16 03:17:0911763 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811764 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911765 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0311766
11767 StaticSocketDataProvider data;
11768 session_deps_.socket_factory->AddSocketDataProvider(&data);
11769
11770 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2011771 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111772 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5511773 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0311774
11775 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3311776 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
11777 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0311778
11779 // Return Init()'s result after the transaction gets destroyed.
11780 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3311781 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0311782}
11783
[email protected]aeefc9e82010-02-19 16:18:2711784// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0111785TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2711786 HttpRequestInfo request;
11787 request.method = "GET";
bncce36dca22015-04-21 22:11:2311788 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011789 request.traffic_annotation =
11790 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2711791
11792 // First transaction will request a resource and receive a Basic challenge
11793 // with realm="first_realm".
11794 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311795 MockWrite(
11796 "GET / HTTP/1.1\r\n"
11797 "Host: www.example.org\r\n"
11798 "Connection: keep-alive\r\n"
11799 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711800 };
11801 MockRead data_reads1[] = {
11802 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11803 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11804 "\r\n"),
11805 };
11806
bnc691fda62016-08-12 00:43:1611807 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2711808 // for first_realm. The server will reject and provide a challenge with
11809 // second_realm.
11810 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311811 MockWrite(
11812 "GET / HTTP/1.1\r\n"
11813 "Host: www.example.org\r\n"
11814 "Connection: keep-alive\r\n"
11815 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
11816 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711817 };
11818 MockRead data_reads2[] = {
11819 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11820 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
11821 "\r\n"),
11822 };
11823
11824 // This again fails, and goes back to first_realm. Make sure that the
11825 // entry is removed from cache.
11826 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2311827 MockWrite(
11828 "GET / HTTP/1.1\r\n"
11829 "Host: www.example.org\r\n"
11830 "Connection: keep-alive\r\n"
11831 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
11832 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711833 };
11834 MockRead data_reads3[] = {
11835 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11836 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11837 "\r\n"),
11838 };
11839
11840 // Try one last time (with the correct password) and get the resource.
11841 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2311842 MockWrite(
11843 "GET / HTTP/1.1\r\n"
11844 "Host: www.example.org\r\n"
11845 "Connection: keep-alive\r\n"
11846 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
11847 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711848 };
11849 MockRead data_reads4[] = {
11850 MockRead("HTTP/1.1 200 OK\r\n"
11851 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5011852 "Content-Length: 5\r\n"
11853 "\r\n"
11854 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2711855 };
11856
Ryan Sleevib8d7ea02018-05-07 20:01:0111857 StaticSocketDataProvider data1(data_reads1, data_writes1);
11858 StaticSocketDataProvider data2(data_reads2, data_writes2);
11859 StaticSocketDataProvider data3(data_reads3, data_writes3);
11860 StaticSocketDataProvider data4(data_reads4, data_writes4);
[email protected]bb88e1d32013-05-03 23:11:0711861 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11862 session_deps_.socket_factory->AddSocketDataProvider(&data2);
11863 session_deps_.socket_factory->AddSocketDataProvider(&data3);
11864 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2711865
[email protected]49639fa2011-12-20 23:22:4111866 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2711867
danakj1fd259a02016-04-16 03:17:0911868 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611869 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011870
[email protected]aeefc9e82010-02-19 16:18:2711871 // Issue the first request with Authorize headers. There should be a
11872 // password prompt for first_realm waiting to be filled in after the
11873 // transaction completes.
tfarina42834112016-09-22 13:38:2011874 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111875 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711876 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111877 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611878 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211879 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811880 base::Optional<AuthChallengeInfo> challenge = response->auth_challenge;
wezca1070932016-05-26 20:30:5211881 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411882 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311883 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411884 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911885 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711886
11887 // Issue the second request with an incorrect password. There should be a
11888 // password prompt for second_realm waiting to be filled in after the
11889 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4111890 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1611891 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
11892 callback2.callback());
robpercival214763f2016-07-01 23:27:0111893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711894 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111895 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611896 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211897 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811898 challenge = response->auth_challenge;
wezca1070932016-05-26 20:30:5211899 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411900 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311901 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411902 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911903 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711904
11905 // Issue the third request with another incorrect password. There should be
11906 // a password prompt for first_realm waiting to be filled in. If the password
11907 // prompt is not present, it indicates that the HttpAuthCacheEntry for
11908 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4111909 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1611910 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
11911 callback3.callback());
robpercival214763f2016-07-01 23:27:0111912 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711913 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0111914 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611915 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211916 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811917 challenge = response->auth_challenge;
wezca1070932016-05-26 20:30:5211918 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411919 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311920 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411921 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911922 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711923
11924 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4111925 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1611926 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
11927 callback4.callback());
robpercival214763f2016-07-01 23:27:0111928 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711929 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0111930 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611931 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211932 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811933 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]aeefc9e82010-02-19 16:18:2711934}
11935
Bence Béky230ac612017-08-30 19:17:0811936// Regression test for https://crbug.com/754395.
11937TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
11938 MockRead data_reads[] = {
11939 MockRead("HTTP/1.1 200 OK\r\n"),
11940 MockRead(kAlternativeServiceHttpHeader),
11941 MockRead("\r\n"),
11942 MockRead("hello world"),
11943 MockRead(SYNCHRONOUS, OK),
11944 };
11945
11946 HttpRequestInfo request;
11947 request.method = "GET";
11948 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011949 request.traffic_annotation =
11950 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0811951
Ryan Sleevib8d7ea02018-05-07 20:01:0111952 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:0811953 session_deps_.socket_factory->AddSocketDataProvider(&data);
11954
11955 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911956 ssl.ssl_info.cert =
11957 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11958 ASSERT_TRUE(ssl.ssl_info.cert);
11959 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811960 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11961
11962 TestCompletionCallback callback;
11963
11964 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11965 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11966
11967 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11968 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11969
11970 url::SchemeHostPort test_server(request.url);
11971 HttpServerProperties* http_server_properties =
11972 session->http_server_properties();
11973 EXPECT_TRUE(
11974 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11975
11976 EXPECT_THAT(callback.WaitForResult(), IsOk());
11977
11978 const HttpResponseInfo* response = trans.GetResponseInfo();
11979 ASSERT_TRUE(response);
11980 ASSERT_TRUE(response->headers);
11981 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11982 EXPECT_FALSE(response->was_fetched_via_spdy);
11983 EXPECT_FALSE(response->was_alpn_negotiated);
11984
11985 std::string response_data;
11986 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11987 EXPECT_EQ("hello world", response_data);
11988
11989 EXPECT_TRUE(
11990 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11991}
11992
bncd16676a2016-07-20 16:23:0111993TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211994 MockRead data_reads[] = {
11995 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311996 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211997 MockRead("\r\n"),
11998 MockRead("hello world"),
11999 MockRead(SYNCHRONOUS, OK),
12000 };
12001
12002 HttpRequestInfo request;
12003 request.method = "GET";
bncb26024382016-06-29 02:39:4512004 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012005 request.traffic_annotation =
12006 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5212007
Ryan Sleevib8d7ea02018-05-07 20:01:0112008 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5212009 session_deps_.socket_factory->AddSocketDataProvider(&data);
12010
bncb26024382016-06-29 02:39:4512011 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912012 ssl.ssl_info.cert =
12013 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12014 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512015 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12016
bncc958faa2015-07-31 18:14:5212017 TestCompletionCallback callback;
12018
danakj1fd259a02016-04-16 03:17:0912019 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612020 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5212021
tfarina42834112016-09-22 13:38:2012022 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112023 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5212024
bncb26024382016-06-29 02:39:4512025 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4012026 HttpServerProperties* http_server_properties =
12027 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412028 EXPECT_TRUE(
12029 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5212030
robpercival214763f2016-07-01 23:27:0112031 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5212032
bnc691fda62016-08-12 00:43:1612033 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212034 ASSERT_TRUE(response);
12035 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5212036 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12037 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212038 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212039
12040 std::string response_data;
bnc691fda62016-08-12 00:43:1612041 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212042 EXPECT_EQ("hello world", response_data);
12043
zhongyic4de03032017-05-19 04:07:3412044 AlternativeServiceInfoVector alternative_service_info_vector =
12045 http_server_properties->GetAlternativeServiceInfos(test_server);
12046 ASSERT_EQ(1u, alternative_service_info_vector.size());
12047 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
12048 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412049 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5212050}
12051
bnce3dd56f2016-06-01 10:37:1112052// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0112053TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112054 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1112055 MockRead data_reads[] = {
12056 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312057 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1112058 MockRead("\r\n"),
12059 MockRead("hello world"),
12060 MockRead(SYNCHRONOUS, OK),
12061 };
12062
12063 HttpRequestInfo request;
12064 request.method = "GET";
12065 request.url = GURL("http://www.example.org/");
12066 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012067 request.traffic_annotation =
12068 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112069
Ryan Sleevib8d7ea02018-05-07 20:01:0112070 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112071 session_deps_.socket_factory->AddSocketDataProvider(&data);
12072
12073 TestCompletionCallback callback;
12074
12075 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612076 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112077
12078 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4012079 HttpServerProperties* http_server_properties =
12080 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412081 EXPECT_TRUE(
12082 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112083
tfarina42834112016-09-22 13:38:2012084 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12086 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1112087
bnc691fda62016-08-12 00:43:1612088 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1112089 ASSERT_TRUE(response);
12090 ASSERT_TRUE(response->headers);
12091 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12092 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212093 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1112094
12095 std::string response_data;
bnc691fda62016-08-12 00:43:1612096 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1112097 EXPECT_EQ("hello world", response_data);
12098
zhongyic4de03032017-05-19 04:07:3412099 EXPECT_TRUE(
12100 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112101}
12102
bnca86731e2017-04-17 12:31:2812103// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2512104// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0112105TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2512106 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2812107 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4512108
bnc8bef8da22016-05-30 01:28:2512109 HttpRequestInfo request;
12110 request.method = "GET";
bncb26024382016-06-29 02:39:4512111 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2512112 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012113 request.traffic_annotation =
12114 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2512115
12116 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12117 StaticSocketDataProvider first_data;
12118 first_data.set_connect_data(mock_connect);
12119 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512120 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612121 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512122 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2512123
12124 MockRead data_reads[] = {
12125 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12126 MockRead(ASYNC, OK),
12127 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112128 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnc8bef8da22016-05-30 01:28:2512129 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12130
12131 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12132
bnc525e175a2016-06-20 12:36:4012133 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2512134 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112135 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
12136 444);
bnc8bef8da22016-05-30 01:28:2512137 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112138 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2512139 url::SchemeHostPort(request.url), alternative_service, expiration);
12140
bnc691fda62016-08-12 00:43:1612141 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2512142 TestCompletionCallback callback;
12143
tfarina42834112016-09-22 13:38:2012144 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2512145 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112146 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2512147}
12148
bnce3dd56f2016-06-01 10:37:1112149// Regression test for https://crbug.com/615497:
12150// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0112151TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112152 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1112153 HttpRequestInfo request;
12154 request.method = "GET";
12155 request.url = GURL("http://www.example.org/");
12156 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012157 request.traffic_annotation =
12158 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112159
12160 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12161 StaticSocketDataProvider first_data;
12162 first_data.set_connect_data(mock_connect);
12163 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
12164
12165 MockRead data_reads[] = {
12166 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12167 MockRead(ASYNC, OK),
12168 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112169 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112170 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12171
12172 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12173
bnc525e175a2016-06-20 12:36:4012174 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1112175 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112176 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1112177 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112178 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1112179 url::SchemeHostPort(request.url), alternative_service, expiration);
12180
bnc691fda62016-08-12 00:43:1612181 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112182 TestCompletionCallback callback;
12183
tfarina42834112016-09-22 13:38:2012184 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1112185 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112186 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1112187}
12188
bncd16676a2016-07-20 16:23:0112189TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0812190 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0912191 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012192 HttpServerProperties* http_server_properties =
12193 session->http_server_properties();
bncb26024382016-06-29 02:39:4512194 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2112195 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0812196 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112197 http_server_properties->SetQuicAlternativeService(
12198 test_server, alternative_service, expiration,
12199 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3412200 EXPECT_EQ(
12201 1u,
12202 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0812203
12204 // Send a clear header.
12205 MockRead data_reads[] = {
12206 MockRead("HTTP/1.1 200 OK\r\n"),
12207 MockRead("Alt-Svc: clear\r\n"),
12208 MockRead("\r\n"),
12209 MockRead("hello world"),
12210 MockRead(SYNCHRONOUS, OK),
12211 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112212 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnc4f575852015-10-14 18:35:0812213 session_deps_.socket_factory->AddSocketDataProvider(&data);
12214
bncb26024382016-06-29 02:39:4512215 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912216 ssl.ssl_info.cert =
12217 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12218 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512219 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12220
bnc4f575852015-10-14 18:35:0812221 HttpRequestInfo request;
12222 request.method = "GET";
bncb26024382016-06-29 02:39:4512223 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012224 request.traffic_annotation =
12225 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0812226
12227 TestCompletionCallback callback;
12228
bnc691fda62016-08-12 00:43:1612229 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0812230
tfarina42834112016-09-22 13:38:2012231 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112232 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0812233
bnc691fda62016-08-12 00:43:1612234 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212235 ASSERT_TRUE(response);
12236 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0812237 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12238 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212239 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0812240
12241 std::string response_data;
bnc691fda62016-08-12 00:43:1612242 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0812243 EXPECT_EQ("hello world", response_data);
12244
zhongyic4de03032017-05-19 04:07:3412245 EXPECT_TRUE(
12246 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0812247}
12248
bncd16676a2016-07-20 16:23:0112249TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5212250 MockRead data_reads[] = {
12251 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312252 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
12253 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5212254 MockRead("hello world"),
12255 MockRead(SYNCHRONOUS, OK),
12256 };
12257
12258 HttpRequestInfo request;
12259 request.method = "GET";
bncb26024382016-06-29 02:39:4512260 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012261 request.traffic_annotation =
12262 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5212263
Ryan Sleevib8d7ea02018-05-07 20:01:0112264 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5212265 session_deps_.socket_factory->AddSocketDataProvider(&data);
12266
bncb26024382016-06-29 02:39:4512267 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912268 ssl.ssl_info.cert =
12269 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12270 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512271 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12272
bncc958faa2015-07-31 18:14:5212273 TestCompletionCallback callback;
12274
danakj1fd259a02016-04-16 03:17:0912275 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612276 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5212277
tfarina42834112016-09-22 13:38:2012278 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112279 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5212280
bncb26024382016-06-29 02:39:4512281 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4012282 HttpServerProperties* http_server_properties =
12283 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412284 EXPECT_TRUE(
12285 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5212286
robpercival214763f2016-07-01 23:27:0112287 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5212288
bnc691fda62016-08-12 00:43:1612289 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212290 ASSERT_TRUE(response);
12291 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5212292 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12293 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212294 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212295
12296 std::string response_data;
bnc691fda62016-08-12 00:43:1612297 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212298 EXPECT_EQ("hello world", response_data);
12299
zhongyic4de03032017-05-19 04:07:3412300 AlternativeServiceInfoVector alternative_service_info_vector =
12301 http_server_properties->GetAlternativeServiceInfos(test_server);
12302 ASSERT_EQ(2u, alternative_service_info_vector.size());
12303
12304 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
12305 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412306 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412307 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
12308 1234);
12309 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5412310 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5212311}
12312
bncd16676a2016-07-20 16:23:0112313TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612314 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212315 HostPortPair alternative("alternative.example.org", 443);
12316 std::string origin_url = "https://origin.example.org:443";
12317 std::string alternative_url = "https://alternative.example.org:443";
12318
12319 // Negotiate HTTP/1.1 with alternative.example.org.
12320 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612321 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212322 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12323
12324 // HTTP/1.1 data for request.
12325 MockWrite http_writes[] = {
12326 MockWrite("GET / HTTP/1.1\r\n"
12327 "Host: alternative.example.org\r\n"
12328 "Connection: keep-alive\r\n\r\n"),
12329 };
12330
12331 MockRead http_reads[] = {
12332 MockRead("HTTP/1.1 200 OK\r\n"
12333 "Content-Type: text/html; charset=iso-8859-1\r\n"
12334 "Content-Length: 40\r\n\r\n"
12335 "first HTTP/1.1 response from alternative"),
12336 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112337 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212338 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12339
12340 StaticSocketDataProvider data_refused;
12341 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12342 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12343
zhongyi3d4a55e72016-04-22 20:36:4612344 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0912345 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012346 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212347 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112348 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0212349 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112350 http_server_properties->SetQuicAlternativeService(
12351 server, alternative_service, expiration,
12352 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0212353 // Mark the QUIC alternative service as broken.
12354 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
12355
zhongyi48704c182015-12-07 07:52:0212356 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612357 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212358 request.method = "GET";
12359 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1012360 request.traffic_annotation =
12361 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12362
zhongyi48704c182015-12-07 07:52:0212363 TestCompletionCallback callback;
12364 NetErrorDetails details;
12365 EXPECT_FALSE(details.quic_broken);
12366
tfarina42834112016-09-22 13:38:2012367 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612368 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212369 EXPECT_TRUE(details.quic_broken);
12370}
12371
bncd16676a2016-07-20 16:23:0112372TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612373 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212374 HostPortPair alternative1("alternative1.example.org", 443);
12375 HostPortPair alternative2("alternative2.example.org", 443);
12376 std::string origin_url = "https://origin.example.org:443";
12377 std::string alternative_url1 = "https://alternative1.example.org:443";
12378 std::string alternative_url2 = "https://alternative2.example.org:443";
12379
12380 // Negotiate HTTP/1.1 with alternative1.example.org.
12381 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612382 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212383 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12384
12385 // HTTP/1.1 data for request.
12386 MockWrite http_writes[] = {
12387 MockWrite("GET / HTTP/1.1\r\n"
12388 "Host: alternative1.example.org\r\n"
12389 "Connection: keep-alive\r\n\r\n"),
12390 };
12391
12392 MockRead http_reads[] = {
12393 MockRead("HTTP/1.1 200 OK\r\n"
12394 "Content-Type: text/html; charset=iso-8859-1\r\n"
12395 "Content-Length: 40\r\n\r\n"
12396 "first HTTP/1.1 response from alternative1"),
12397 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112398 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212399 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12400
12401 StaticSocketDataProvider data_refused;
12402 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12403 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12404
danakj1fd259a02016-04-16 03:17:0912405 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012406 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212407 session->http_server_properties();
12408
zhongyi3d4a55e72016-04-22 20:36:4612409 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0212410 AlternativeServiceInfoVector alternative_service_info_vector;
12411 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
12412
bnc3472afd2016-11-17 15:27:2112413 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2112414 alternative_service_info_vector.push_back(
12415 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12416 alternative_service1, expiration,
12417 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2112418 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2112419 alternative_service_info_vector.push_back(
12420 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12421 alternative_service2, expiration,
12422 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0212423
12424 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4612425 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0212426
12427 // Mark one of the QUIC alternative service as broken.
12428 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3412429 EXPECT_EQ(2u,
12430 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0212431
zhongyi48704c182015-12-07 07:52:0212432 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612433 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212434 request.method = "GET";
12435 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1012436 request.traffic_annotation =
12437 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12438
zhongyi48704c182015-12-07 07:52:0212439 TestCompletionCallback callback;
12440 NetErrorDetails details;
12441 EXPECT_FALSE(details.quic_broken);
12442
tfarina42834112016-09-22 13:38:2012443 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612444 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212445 EXPECT_FALSE(details.quic_broken);
12446}
12447
bncd16676a2016-07-20 16:23:0112448TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4212449 HttpRequestInfo request;
12450 request.method = "GET";
bncb26024382016-06-29 02:39:4512451 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012452 request.traffic_annotation =
12453 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4212454
[email protected]d973e99a2012-02-17 21:02:3612455 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4212456 StaticSocketDataProvider first_data;
12457 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712458 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512459 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612460 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512461 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4212462
12463 MockRead data_reads[] = {
12464 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12465 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612466 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4212467 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112468 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712469 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4212470
danakj1fd259a02016-04-16 03:17:0912471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4212472
bnc525e175a2016-06-20 12:36:4012473 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312474 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4612475 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1112476 // Port must be < 1024, or the header will be ignored (since initial port was
12477 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2112478 // Port is ignored by MockConnect anyway.
12479 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12480 666);
bnc7dc7e1b42015-07-28 14:43:1212481 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112482 http_server_properties->SetHttp2AlternativeService(
12483 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4212484
bnc691fda62016-08-12 00:43:1612485 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112486 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4212487
tfarina42834112016-09-22 13:38:2012488 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12490 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4212491
bnc691fda62016-08-12 00:43:1612492 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212493 ASSERT_TRUE(response);
12494 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4212495 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12496
12497 std::string response_data;
bnc691fda62016-08-12 00:43:1612498 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4212499 EXPECT_EQ("hello world", response_data);
12500
zhongyic4de03032017-05-19 04:07:3412501 const AlternativeServiceInfoVector alternative_service_info_vector =
12502 http_server_properties->GetAlternativeServiceInfos(server);
12503 ASSERT_EQ(1u, alternative_service_info_vector.size());
12504 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412505 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412506 EXPECT_TRUE(
12507 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4212508}
12509
bnc55ff9da2015-08-19 18:42:3512510// Ensure that we are not allowed to redirect traffic via an alternate protocol
12511// to an unrestricted (port >= 1024) when the original traffic was on a
12512// restricted port (port < 1024). Ensure that we can redirect in all other
12513// cases.
bncd16676a2016-07-20 16:23:0112514TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1112515 HttpRequestInfo restricted_port_request;
12516 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512517 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112518 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012519 restricted_port_request.traffic_annotation =
12520 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112521
[email protected]d973e99a2012-02-17 21:02:3612522 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112523 StaticSocketDataProvider first_data;
12524 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712525 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112526
12527 MockRead data_reads[] = {
12528 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12529 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612530 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112531 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112532 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712533 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512534 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612535 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512536 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112537
danakj1fd259a02016-04-16 03:17:0912538 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112539
bnc525e175a2016-06-20 12:36:4012540 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312541 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112542 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112543 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12544 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212545 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112546 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612547 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012548 expiration);
[email protected]3912662a32011-10-04 00:51:1112549
bnc691fda62016-08-12 00:43:1612550 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112551 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112552
tfarina42834112016-09-22 13:38:2012553 int rv = trans.Start(&restricted_port_request, callback.callback(),
12554 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112556 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0112557 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1912558}
[email protected]3912662a32011-10-04 00:51:1112559
bnc55ff9da2015-08-19 18:42:3512560// Ensure that we are allowed to redirect traffic via an alternate protocol to
12561// an unrestricted (port >= 1024) when the original traffic was on a restricted
12562// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0112563TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0712564 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1912565
12566 HttpRequestInfo restricted_port_request;
12567 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512568 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1912569 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012570 restricted_port_request.traffic_annotation =
12571 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1912572
12573 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12574 StaticSocketDataProvider first_data;
12575 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712576 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1912577
12578 MockRead data_reads[] = {
12579 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12580 MockRead("hello world"),
12581 MockRead(ASYNC, OK),
12582 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112583 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712584 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512585 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612586 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512587 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1912588
danakj1fd259a02016-04-16 03:17:0912589 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1912590
bnc525e175a2016-06-20 12:36:4012591 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1912592 session->http_server_properties();
12593 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112594 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12595 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212596 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112597 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612598 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012599 expiration);
[email protected]c54c6962013-02-01 04:53:1912600
bnc691fda62016-08-12 00:43:1612601 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1912602 TestCompletionCallback callback;
12603
tfarina42834112016-09-22 13:38:2012604 EXPECT_EQ(ERR_IO_PENDING,
12605 trans.Start(&restricted_port_request, callback.callback(),
12606 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1912607 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0112608 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112609}
12610
bnc55ff9da2015-08-19 18:42:3512611// Ensure that we are not allowed to redirect traffic via an alternate protocol
12612// to an unrestricted (port >= 1024) when the original traffic was on a
12613// restricted port (port < 1024). Ensure that we can redirect in all other
12614// cases.
bncd16676a2016-07-20 16:23:0112615TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1112616 HttpRequestInfo restricted_port_request;
12617 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512618 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112619 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012620 restricted_port_request.traffic_annotation =
12621 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112622
[email protected]d973e99a2012-02-17 21:02:3612623 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112624 StaticSocketDataProvider first_data;
12625 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712626 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112627
12628 MockRead data_reads[] = {
12629 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12630 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612631 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112632 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112633 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712634 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112635
bncb26024382016-06-29 02:39:4512636 SSLSocketDataProvider ssl(ASYNC, OK);
12637 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12638
danakj1fd259a02016-04-16 03:17:0912639 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112640
bnc525e175a2016-06-20 12:36:4012641 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312642 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112643 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112644 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12645 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212646 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112647 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612648 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012649 expiration);
[email protected]3912662a32011-10-04 00:51:1112650
bnc691fda62016-08-12 00:43:1612651 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112652 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112653
tfarina42834112016-09-22 13:38:2012654 int rv = trans.Start(&restricted_port_request, callback.callback(),
12655 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112656 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112657 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112658 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112659}
12660
bnc55ff9da2015-08-19 18:42:3512661// Ensure that we are not allowed to redirect traffic via an alternate protocol
12662// to an unrestricted (port >= 1024) when the original traffic was on a
12663// restricted port (port < 1024). Ensure that we can redirect in all other
12664// cases.
bncd16676a2016-07-20 16:23:0112665TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1112666 HttpRequestInfo unrestricted_port_request;
12667 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512668 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112669 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012670 unrestricted_port_request.traffic_annotation =
12671 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112672
[email protected]d973e99a2012-02-17 21:02:3612673 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112674 StaticSocketDataProvider first_data;
12675 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712676 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112677
12678 MockRead data_reads[] = {
12679 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12680 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612681 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112682 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112683 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712684 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512685 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612686 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512687 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112688
danakj1fd259a02016-04-16 03:17:0912689 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112690
bnc525e175a2016-06-20 12:36:4012691 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312692 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112693 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112694 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12695 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212696 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112697 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612698 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012699 expiration);
[email protected]3912662a32011-10-04 00:51:1112700
bnc691fda62016-08-12 00:43:1612701 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112702 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112703
bnc691fda62016-08-12 00:43:1612704 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012705 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112706 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112707 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112708 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112709}
12710
bnc55ff9da2015-08-19 18:42:3512711// Ensure that we are not allowed to redirect traffic via an alternate protocol
12712// to an unrestricted (port >= 1024) when the original traffic was on a
12713// restricted port (port < 1024). Ensure that we can redirect in all other
12714// cases.
bncd16676a2016-07-20 16:23:0112715TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1112716 HttpRequestInfo unrestricted_port_request;
12717 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512718 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112719 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012720 unrestricted_port_request.traffic_annotation =
12721 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112722
[email protected]d973e99a2012-02-17 21:02:3612723 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112724 StaticSocketDataProvider first_data;
12725 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712726 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112727
12728 MockRead data_reads[] = {
12729 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12730 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612731 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112732 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112733 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712734 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112735
bncb26024382016-06-29 02:39:4512736 SSLSocketDataProvider ssl(ASYNC, OK);
12737 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12738
danakj1fd259a02016-04-16 03:17:0912739 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112740
bnc525e175a2016-06-20 12:36:4012741 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312742 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2212743 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2112744 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12745 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212746 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112747 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612748 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012749 expiration);
[email protected]3912662a32011-10-04 00:51:1112750
bnc691fda62016-08-12 00:43:1612751 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112752 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112753
bnc691fda62016-08-12 00:43:1612754 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012755 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112756 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112757 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0112758 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112759}
12760
bnc55ff9da2015-08-19 18:42:3512761// Ensure that we are not allowed to redirect traffic via an alternate protocol
Xida Chen9bfe0b62018-04-24 19:52:2112762// to an unsafe port, and that we resume the second HttpStreamFactory::Job once
12763// the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0112764TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0212765 HttpRequestInfo request;
12766 request.method = "GET";
bncce36dca22015-04-21 22:11:2312767 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012768 request.traffic_annotation =
12769 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0212770
12771 // The alternate protocol request will error out before we attempt to connect,
12772 // so only the standard HTTP request will try to connect.
12773 MockRead data_reads[] = {
12774 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12775 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612776 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0212777 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112778 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712779 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0212780
danakj1fd259a02016-04-16 03:17:0912781 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0212782
bnc525e175a2016-06-20 12:36:4012783 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0212784 session->http_server_properties();
12785 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2112786 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12787 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1212788 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112789 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612790 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0212791
bnc691fda62016-08-12 00:43:1612792 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0212793 TestCompletionCallback callback;
12794
tfarina42834112016-09-22 13:38:2012795 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112796 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0212797 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0112798 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212799
bnc691fda62016-08-12 00:43:1612800 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212801 ASSERT_TRUE(response);
12802 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0212803 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12804
12805 std::string response_data;
bnc691fda62016-08-12 00:43:1612806 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212807 EXPECT_EQ("hello world", response_data);
12808}
12809
bncd16676a2016-07-20 16:23:0112810TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5412811 HttpRequestInfo request;
12812 request.method = "GET";
bncb26024382016-06-29 02:39:4512813 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012814 request.traffic_annotation =
12815 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412816
12817 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212818 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312819 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212820 MockRead("\r\n"),
12821 MockRead("hello world"),
12822 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12823 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5412824
Ryan Sleevib8d7ea02018-05-07 20:01:0112825 StaticSocketDataProvider first_transaction(data_reads,
12826 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712827 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512828 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612829 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512830 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412831
bnc032658ba2016-09-26 18:17:1512832 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412833
Ryan Hamilton0239aac2018-05-19 00:03:1312834 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512835 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112836 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412837
Raul Tambre94493c652019-03-11 17:18:3512838 spdy::SpdySerializedFrame resp(
12839 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1312840 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412841 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112842 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412843 };
12844
Ryan Sleevib8d7ea02018-05-07 20:01:0112845 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712846 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412847
[email protected]d973e99a2012-02-17 21:02:3612848 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112849 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512850 hanging_non_alternate_protocol_socket.set_connect_data(
12851 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712852 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512853 &hanging_non_alternate_protocol_socket);
12854
[email protected]49639fa2011-12-20 23:22:4112855 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412856
danakj1fd259a02016-04-16 03:17:0912857 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812858 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912859 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412860
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));
12863 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412864
12865 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212866 ASSERT_TRUE(response);
12867 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412868 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12869
12870 std::string response_data;
robpercival214763f2016-07-01 23:27:0112871 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412872 EXPECT_EQ("hello world", response_data);
12873
bnc87dcefc2017-05-25 12:47:5812874 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912875 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412876
tfarina42834112016-09-22 13:38:2012877 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112878 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12879 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412880
12881 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212882 ASSERT_TRUE(response);
12883 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212884 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312885 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212886 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412887
robpercival214763f2016-07-01 23:27:0112888 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412889 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5412890}
12891
bncd16676a2016-07-20 16:23:0112892TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5512893 HttpRequestInfo request;
12894 request.method = "GET";
bncb26024382016-06-29 02:39:4512895 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012896 request.traffic_annotation =
12897 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512898
bncb26024382016-06-29 02:39:4512899 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5512900 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212901 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312902 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212903 MockRead("\r\n"),
12904 MockRead("hello world"),
12905 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12906 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512907 };
12908
Ryan Sleevib8d7ea02018-05-07 20:01:0112909 StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
bncb26024382016-06-29 02:39:4512910 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5512911
bncb26024382016-06-29 02:39:4512912 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912913 ssl_http11.ssl_info.cert =
12914 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12915 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4512916 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
12917
12918 // Second transaction starts an alternative and a non-alternative Job.
12919 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3612920 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112921 StaticSocketDataProvider hanging_socket1;
mmenkecc2298e2015-12-07 18:20:1812922 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1812923 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
12924
Ryan Sleevib8d7ea02018-05-07 20:01:0112925 StaticSocketDataProvider hanging_socket2;
mmenkecc2298e2015-12-07 18:20:1812926 hanging_socket2.set_connect_data(never_finishing_connect);
12927 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5512928
bncb26024382016-06-29 02:39:4512929 // Third transaction starts an alternative and a non-alternative job.
12930 // The non-alternative job hangs, but the alternative one succeeds.
12931 // The second transaction, still pending, binds to this socket.
Ryan Hamilton0239aac2018-05-19 00:03:1312932 spdy::SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4512933 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1312934 spdy::SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4512935 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5512936 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112937 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5512938 };
Raul Tambre94493c652019-03-11 17:18:3512939 spdy::SpdySerializedFrame resp1(
12940 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1312941 spdy::SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
Raul Tambre94493c652019-03-11 17:18:3512942 spdy::SpdySerializedFrame resp2(
12943 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1312944 spdy::SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5512945 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112946 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
12947 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1312948 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5512949 };
12950
Ryan Sleevib8d7ea02018-05-07 20:01:0112951 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712952 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5512953
bnc032658ba2016-09-26 18:17:1512954 AddSSLSocketData();
bncb26024382016-06-29 02:39:4512955
Ryan Sleevib8d7ea02018-05-07 20:01:0112956 StaticSocketDataProvider hanging_socket3;
mmenkecc2298e2015-12-07 18:20:1812957 hanging_socket3.set_connect_data(never_finishing_connect);
12958 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512959
danakj1fd259a02016-04-16 03:17:0912960 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112961 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012962 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512963
tfarina42834112016-09-22 13:38:2012964 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112965 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12966 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512967
12968 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212969 ASSERT_TRUE(response);
12970 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512971 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12972
12973 std::string response_data;
robpercival214763f2016-07-01 23:27:0112974 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512975 EXPECT_EQ("hello world", response_data);
12976
[email protected]49639fa2011-12-20 23:22:4112977 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012978 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012979 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112980 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512981
[email protected]49639fa2011-12-20 23:22:4112982 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012983 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012984 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512986
robpercival214763f2016-07-01 23:27:0112987 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12988 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512989
12990 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212991 ASSERT_TRUE(response);
12992 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212993 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512994 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212995 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112996 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512997 EXPECT_EQ("hello!", response_data);
12998
12999 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5213000 ASSERT_TRUE(response);
13001 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213002 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5513003 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213004 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113005 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513006 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5513007}
13008
bncd16676a2016-07-20 16:23:0113009TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
Bence Békybcae37092018-06-12 04:18:5313010 session_deps_.host_resolver->set_synchronous_mode(true);
13011
[email protected]2d6728692011-03-12 01:39:5513012 HttpRequestInfo request;
13013 request.method = "GET";
bncb26024382016-06-29 02:39:4513014 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013015 request.traffic_annotation =
13016 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5513017
13018 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213019 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313020 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213021 MockRead("\r\n"),
13022 MockRead("hello world"),
13023 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13024 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5513025 };
13026
Ryan Sleevib8d7ea02018-05-07 20:01:0113027 StaticSocketDataProvider first_transaction(data_reads,
13028 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713029 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5513030
[email protected]8ddf8322012-02-23 18:08:0613031 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4913032 ssl.ssl_info.cert =
13033 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
13034 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0713035 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5513036
[email protected]d973e99a2012-02-17 21:02:3613037 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113038 StaticSocketDataProvider hanging_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513039 hanging_alternate_protocol_socket.set_connect_data(
13040 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713041 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513042 &hanging_alternate_protocol_socket);
13043
bncb26024382016-06-29 02:39:4513044 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
Ryan Sleevib8d7ea02018-05-07 20:01:0113045 StaticSocketDataProvider second_transaction(data_reads,
13046 base::span<MockWrite>());
mmenkecc2298e2015-12-07 18:20:1813047 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4513048 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5513049
[email protected]49639fa2011-12-20 23:22:4113050 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5513051
danakj1fd259a02016-04-16 03:17:0913052 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813053 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913054 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5513055
tfarina42834112016-09-22 13:38:2013056 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113057 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13058 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513059
13060 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213061 ASSERT_TRUE(response);
13062 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513063 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13064
13065 std::string response_data;
robpercival214763f2016-07-01 23:27:0113066 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513067 EXPECT_EQ("hello world", response_data);
13068
bnc87dcefc2017-05-25 12:47:5813069 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913070 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5513071
tfarina42834112016-09-22 13:38:2013072 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13074 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513075
13076 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213077 ASSERT_TRUE(response);
13078 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513079 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13080 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213081 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5513082
robpercival214763f2016-07-01 23:27:0113083 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513084 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5513085}
13086
bnc2e884782016-08-11 19:45:1913087// Test that proxy is resolved using the origin url,
13088// regardless of the alternative server.
13089TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
13090 // Configure proxy to bypass www.example.org, which is the origin URL.
13091 ProxyConfig proxy_config;
13092 proxy_config.proxy_rules().ParseFromString("myproxy:70");
13093 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4913094 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
13095 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1913096
13097 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1913098 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1913099 &capturing_proxy_resolver);
13100
13101 TestNetLog net_log;
13102
Bence Béky53a5aef2018-03-29 21:54:1213103 session_deps_.proxy_resolution_service =
13104 std::make_unique<ProxyResolutionService>(
13105 std::move(proxy_config_service), std::move(proxy_resolver_factory),
13106 &net_log);
bnc2e884782016-08-11 19:45:1913107
13108 session_deps_.net_log = &net_log;
13109
13110 // Configure alternative service with a hostname that is not bypassed by the
13111 // proxy.
13112 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13113 HttpServerProperties* http_server_properties =
13114 session->http_server_properties();
13115 url::SchemeHostPort server("https", "www.example.org", 443);
13116 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2113117 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1913118 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2113119 http_server_properties->SetHttp2AlternativeService(
13120 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1913121
13122 // Non-alternative job should hang.
13123 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113124 StaticSocketDataProvider hanging_alternate_protocol_socket;
bnc2e884782016-08-11 19:45:1913125 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
13126 session_deps_.socket_factory->AddSocketDataProvider(
13127 &hanging_alternate_protocol_socket);
13128
bnc032658ba2016-09-26 18:17:1513129 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1913130
13131 HttpRequestInfo request;
13132 request.method = "GET";
13133 request.url = GURL("https://www.example.org/");
13134 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1013135 request.traffic_annotation =
13136 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1913137
Ryan Hamilton0239aac2018-05-19 00:03:1313138 spdy::SpdySerializedFrame req(
bnc2e884782016-08-11 19:45:1913139 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
13140
13141 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
13142
Ryan Hamilton0239aac2018-05-19 00:03:1313143 spdy::SpdySerializedFrame resp(
13144 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13145 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc2e884782016-08-11 19:45:1913146 MockRead spdy_reads[] = {
13147 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
13148 };
13149
Ryan Sleevib8d7ea02018-05-07 20:01:0113150 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
bnc2e884782016-08-11 19:45:1913151 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
13152
13153 TestCompletionCallback callback;
13154
13155 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13156
tfarina42834112016-09-22 13:38:2013157 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1913158 EXPECT_THAT(callback.GetResult(rv), IsOk());
13159
13160 const HttpResponseInfo* response = trans.GetResponseInfo();
13161 ASSERT_TRUE(response);
13162 ASSERT_TRUE(response->headers);
13163 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13164 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213165 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1913166
13167 std::string response_data;
13168 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13169 EXPECT_EQ("hello!", response_data);
13170
13171 // Origin host bypasses proxy, no resolution should have happened.
13172 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
13173}
13174
bncd16676a2016-07-20 16:23:0113175TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1113176 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4213177 proxy_config.set_auto_detect(true);
13178 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1113179
sammc5dd160c2015-04-02 02:43:1313180 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4913181 session_deps_.proxy_resolution_service =
13182 std::make_unique<ProxyResolutionService>(
13183 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
13184 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
13185 std::make_unique<CapturingProxyResolverFactory>(
13186 &capturing_proxy_resolver),
13187 nullptr);
vishal.b62985ca92015-04-17 08:45:5113188 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0713189 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1113190
13191 HttpRequestInfo request;
13192 request.method = "GET";
bncb26024382016-06-29 02:39:4513193 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013194 request.traffic_annotation =
13195 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1113196
13197 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213198 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313199 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213200 MockRead("\r\n"),
13201 MockRead("hello world"),
13202 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13203 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1113204 };
13205
Ryan Sleevib8d7ea02018-05-07 20:01:0113206 StaticSocketDataProvider first_transaction(data_reads,
13207 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713208 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513209 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613210 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513211 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1113212
bnc032658ba2016-09-26 18:17:1513213 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1113214
Ryan Hamilton0239aac2018-05-19 00:03:1313215 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513216 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1113217 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313218 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2513219 "CONNECT www.example.org:443 HTTP/1.1\r\n"
13220 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1313221 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4113222 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1113223 };
13224
[email protected]d911f1b2010-05-05 22:39:4213225 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
13226
Raul Tambre94493c652019-03-11 17:18:3513227 spdy::SpdySerializedFrame resp(
13228 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1313229 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1113230 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113231 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
13232 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1113233 };
13234
Ryan Sleevib8d7ea02018-05-07 20:01:0113235 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713236 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1113237
[email protected]d973e99a2012-02-17 21:02:3613238 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113239 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513240 hanging_non_alternate_protocol_socket.set_connect_data(
13241 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713242 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513243 &hanging_non_alternate_protocol_socket);
13244
[email protected]49639fa2011-12-20 23:22:4113245 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1113246
danakj1fd259a02016-04-16 03:17:0913247 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813248 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913249 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113250
tfarina42834112016-09-22 13:38:2013251 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4113252 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13253 EXPECT_THAT(callback.WaitForResult(), IsOk());
13254
13255 const HttpResponseInfo* response = trans->GetResponseInfo();
13256 ASSERT_TRUE(response);
13257 ASSERT_TRUE(response->headers);
13258 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
13259 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213260 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4113261
13262 std::string response_data;
13263 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
13264 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1113265
bnc87dcefc2017-05-25 12:47:5813266 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913267 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113268
tfarina42834112016-09-22 13:38:2013269 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113270 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13271 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1113272
mmenkea2dcd3bf2016-08-16 21:49:4113273 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213274 ASSERT_TRUE(response);
13275 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213276 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313277 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213278 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1113279
robpercival214763f2016-07-01 23:27:0113280 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1113281 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4513282 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
13283 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313284 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2313285 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313286 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1113287
[email protected]029c83b62013-01-24 05:28:2013288 LoadTimingInfo load_timing_info;
13289 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
13290 TestLoadTimingNotReusedWithPac(load_timing_info,
13291 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1113292}
[email protected]631f1322010-04-30 17:59:1113293
bncd16676a2016-07-20 16:23:0113294TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4813295 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5413296 HttpRequestInfo request;
13297 request.method = "GET";
bncb26024382016-06-29 02:39:4513298 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013299 request.traffic_annotation =
13300 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5413301
13302 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213303 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313304 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213305 MockRead("\r\n"),
13306 MockRead("hello world"),
13307 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5413308 };
13309
Ryan Sleevib8d7ea02018-05-07 20:01:0113310 StaticSocketDataProvider first_transaction(data_reads,
13311 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713312 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513313 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613314 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513315 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5413316
bnc032658ba2016-09-26 18:17:1513317 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5413318
Ryan Hamilton0239aac2018-05-19 00:03:1313319 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513320 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113321 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5413322
Raul Tambre94493c652019-03-11 17:18:3513323 spdy::SpdySerializedFrame resp(
13324 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1313325 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5413326 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113327 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5413328 };
13329
Ryan Sleevib8d7ea02018-05-07 20:01:0113330 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713331 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5413332
[email protected]83039bb2011-12-09 18:43:5513333 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5413334
danakj1fd259a02016-04-16 03:17:0913335 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5413336
bnc87dcefc2017-05-25 12:47:5813337 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913338 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413339
tfarina42834112016-09-22 13:38:2013340 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113341 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13342 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413343
13344 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213345 ASSERT_TRUE(response);
13346 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5413347 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13348
13349 std::string response_data;
robpercival214763f2016-07-01 23:27:0113350 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413351 EXPECT_EQ("hello world", response_data);
13352
13353 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2513354 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013355 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1113356 PRIVACY_MODE_DISABLED,
13357 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2713358 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213359 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3813360
bnc87dcefc2017-05-25 12:47:5813361 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913362 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413363
tfarina42834112016-09-22 13:38:2013364 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113365 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13366 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413367
13368 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213369 ASSERT_TRUE(response);
13370 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213371 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313372 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213373 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5413374
robpercival214763f2016-07-01 23:27:0113375 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413376 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4213377}
13378
[email protected]044de0642010-06-17 10:42:1513379// GenerateAuthToken is a mighty big test.
13380// It tests all permutation of GenerateAuthToken behavior:
13381// - Synchronous and Asynchronous completion.
13382// - OK or error on completion.
13383// - Direct connection, non-authenticating proxy, and authenticating proxy.
13384// - HTTP or HTTPS backend (to include proxy tunneling).
13385// - Non-authenticating and authenticating backend.
13386//
[email protected]fe3b7dc2012-02-03 19:52:0913387// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1513388// problems generating an auth token for an authenticating proxy, we don't
13389// need to test all permutations of the backend server).
13390//
13391// The test proceeds by going over each of the configuration cases, and
13392// potentially running up to three rounds in each of the tests. The TestConfig
13393// specifies both the configuration for the test as well as the expectations
13394// for the results.
bncd16676a2016-07-20 16:23:0113395TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5013396 static const char kServer[] = "http://www.example.com";
13397 static const char kSecureServer[] = "https://www.example.com";
13398 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1513399
13400 enum AuthTiming {
13401 AUTH_NONE,
13402 AUTH_SYNC,
13403 AUTH_ASYNC,
13404 };
13405
13406 const MockWrite kGet(
13407 "GET / HTTP/1.1\r\n"
13408 "Host: www.example.com\r\n"
13409 "Connection: keep-alive\r\n\r\n");
13410 const MockWrite kGetProxy(
13411 "GET http://www.example.com/ HTTP/1.1\r\n"
13412 "Host: www.example.com\r\n"
13413 "Proxy-Connection: keep-alive\r\n\r\n");
13414 const MockWrite kGetAuth(
13415 "GET / HTTP/1.1\r\n"
13416 "Host: www.example.com\r\n"
13417 "Connection: keep-alive\r\n"
13418 "Authorization: auth_token\r\n\r\n");
13419 const MockWrite kGetProxyAuth(
13420 "GET http://www.example.com/ HTTP/1.1\r\n"
13421 "Host: www.example.com\r\n"
13422 "Proxy-Connection: keep-alive\r\n"
13423 "Proxy-Authorization: auth_token\r\n\r\n");
13424 const MockWrite kGetAuthThroughProxy(
13425 "GET http://www.example.com/ HTTP/1.1\r\n"
13426 "Host: www.example.com\r\n"
13427 "Proxy-Connection: keep-alive\r\n"
13428 "Authorization: auth_token\r\n\r\n");
13429 const MockWrite kGetAuthWithProxyAuth(
13430 "GET http://www.example.com/ HTTP/1.1\r\n"
13431 "Host: www.example.com\r\n"
13432 "Proxy-Connection: keep-alive\r\n"
13433 "Proxy-Authorization: auth_token\r\n"
13434 "Authorization: auth_token\r\n\r\n");
13435 const MockWrite kConnect(
13436 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713437 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513438 "Proxy-Connection: keep-alive\r\n\r\n");
13439 const MockWrite kConnectProxyAuth(
13440 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713441 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513442 "Proxy-Connection: keep-alive\r\n"
13443 "Proxy-Authorization: auth_token\r\n\r\n");
13444
13445 const MockRead kSuccess(
13446 "HTTP/1.1 200 OK\r\n"
13447 "Content-Type: text/html; charset=iso-8859-1\r\n"
13448 "Content-Length: 3\r\n\r\n"
13449 "Yes");
13450 const MockRead kFailure(
13451 "Should not be called.");
13452 const MockRead kServerChallenge(
13453 "HTTP/1.1 401 Unauthorized\r\n"
13454 "WWW-Authenticate: Mock realm=server\r\n"
13455 "Content-Type: text/html; charset=iso-8859-1\r\n"
13456 "Content-Length: 14\r\n\r\n"
13457 "Unauthorized\r\n");
13458 const MockRead kProxyChallenge(
13459 "HTTP/1.1 407 Unauthorized\r\n"
13460 "Proxy-Authenticate: Mock realm=proxy\r\n"
13461 "Proxy-Connection: close\r\n"
13462 "Content-Type: text/html; charset=iso-8859-1\r\n"
13463 "Content-Length: 14\r\n\r\n"
13464 "Unauthorized\r\n");
13465 const MockRead kProxyConnected(
13466 "HTTP/1.1 200 Connection Established\r\n\r\n");
13467
13468 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
13469 // no constructors, but the C++ compiler on Windows warns about
13470 // unspecified data in compound literals. So, moved to using constructors,
13471 // and TestRound's created with the default constructor should not be used.
13472 struct TestRound {
13473 TestRound()
Raul Tambre94493c652019-03-11 17:18:3513474 : expected_rv(ERR_UNEXPECTED),
13475 extra_write(nullptr),
13476 extra_read(nullptr) {}
Raul Tambre8335a6d2019-02-21 16:57:4313477 TestRound(const MockWrite& write_arg,
13478 const MockRead& read_arg,
[email protected]044de0642010-06-17 10:42:1513479 int expected_rv_arg)
13480 : write(write_arg),
13481 read(read_arg),
13482 expected_rv(expected_rv_arg),
Raul Tambre94493c652019-03-11 17:18:3513483 extra_write(nullptr),
13484 extra_read(nullptr) {}
[email protected]044de0642010-06-17 10:42:1513485 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
13486 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0113487 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1513488 : write(write_arg),
13489 read(read_arg),
13490 expected_rv(expected_rv_arg),
13491 extra_write(extra_write_arg),
13492 extra_read(extra_read_arg) {
13493 }
13494 MockWrite write;
13495 MockRead read;
13496 int expected_rv;
13497 const MockWrite* extra_write;
13498 const MockRead* extra_read;
13499 };
13500
13501 static const int kNoSSL = 500;
13502
13503 struct TestConfig {
asanka463ca4262016-11-16 02:34:3113504 int line_number;
thestig9d3bb0c2015-01-24 00:49:5113505 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1513506 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3113507 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5113508 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1513509 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3113510 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1513511 int num_auth_rounds;
13512 int first_ssl_round;
asankae2257db2016-10-11 22:03:1613513 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1513514 } test_configs[] = {
asankac93076192016-10-03 15:46:0213515 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113516 {__LINE__,
13517 nullptr,
asankac93076192016-10-03 15:46:0213518 AUTH_NONE,
13519 OK,
13520 kServer,
13521 AUTH_NONE,
13522 OK,
13523 1,
13524 kNoSSL,
13525 {TestRound(kGet, kSuccess, OK)}},
13526 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113527 {__LINE__,
13528 nullptr,
asankac93076192016-10-03 15:46:0213529 AUTH_NONE,
13530 OK,
13531 kServer,
13532 AUTH_SYNC,
13533 OK,
13534 2,
13535 kNoSSL,
13536 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513537 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113538 {__LINE__,
13539 nullptr,
asankac93076192016-10-03 15:46:0213540 AUTH_NONE,
13541 OK,
13542 kServer,
13543 AUTH_SYNC,
13544 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613545 3,
13546 kNoSSL,
13547 {TestRound(kGet, kServerChallenge, OK),
13548 TestRound(kGet, kServerChallenge, OK),
13549 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113550 {__LINE__,
13551 nullptr,
asankae2257db2016-10-11 22:03:1613552 AUTH_NONE,
13553 OK,
13554 kServer,
13555 AUTH_SYNC,
13556 ERR_UNSUPPORTED_AUTH_SCHEME,
13557 2,
13558 kNoSSL,
13559 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113560 {__LINE__,
13561 nullptr,
asankae2257db2016-10-11 22:03:1613562 AUTH_NONE,
13563 OK,
13564 kServer,
13565 AUTH_SYNC,
13566 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
13567 2,
13568 kNoSSL,
13569 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113570 {__LINE__,
13571 kProxy,
asankae2257db2016-10-11 22:03:1613572 AUTH_SYNC,
13573 ERR_FAILED,
13574 kServer,
13575 AUTH_NONE,
13576 OK,
13577 2,
13578 kNoSSL,
13579 {TestRound(kGetProxy, kProxyChallenge, OK),
13580 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113581 {__LINE__,
13582 kProxy,
asankae2257db2016-10-11 22:03:1613583 AUTH_ASYNC,
13584 ERR_FAILED,
13585 kServer,
13586 AUTH_NONE,
13587 OK,
13588 2,
13589 kNoSSL,
13590 {TestRound(kGetProxy, kProxyChallenge, OK),
13591 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113592 {__LINE__,
13593 nullptr,
asankae2257db2016-10-11 22:03:1613594 AUTH_NONE,
13595 OK,
13596 kServer,
13597 AUTH_SYNC,
13598 ERR_FAILED,
asankac93076192016-10-03 15:46:0213599 2,
13600 kNoSSL,
13601 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613602 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113603 {__LINE__,
13604 nullptr,
asankae2257db2016-10-11 22:03:1613605 AUTH_NONE,
13606 OK,
13607 kServer,
13608 AUTH_ASYNC,
13609 ERR_FAILED,
13610 2,
13611 kNoSSL,
13612 {TestRound(kGet, kServerChallenge, OK),
13613 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113614 {__LINE__,
13615 nullptr,
asankac93076192016-10-03 15:46:0213616 AUTH_NONE,
13617 OK,
13618 kServer,
13619 AUTH_ASYNC,
13620 OK,
13621 2,
13622 kNoSSL,
13623 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513624 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113625 {__LINE__,
13626 nullptr,
asankac93076192016-10-03 15:46:0213627 AUTH_NONE,
13628 OK,
13629 kServer,
13630 AUTH_ASYNC,
13631 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613632 3,
asankac93076192016-10-03 15:46:0213633 kNoSSL,
13634 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613635 // The second round uses a HttpAuthHandlerMock that always succeeds.
13636 TestRound(kGet, kServerChallenge, OK),
13637 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213638 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113639 {__LINE__,
13640 kProxy,
asankac93076192016-10-03 15:46:0213641 AUTH_NONE,
13642 OK,
13643 kServer,
13644 AUTH_NONE,
13645 OK,
13646 1,
13647 kNoSSL,
13648 {TestRound(kGetProxy, kSuccess, OK)}},
13649 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113650 {__LINE__,
13651 kProxy,
asankac93076192016-10-03 15:46:0213652 AUTH_NONE,
13653 OK,
13654 kServer,
13655 AUTH_SYNC,
13656 OK,
13657 2,
13658 kNoSSL,
13659 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513660 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113661 {__LINE__,
13662 kProxy,
asankac93076192016-10-03 15:46:0213663 AUTH_NONE,
13664 OK,
13665 kServer,
13666 AUTH_SYNC,
13667 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613668 3,
asankac93076192016-10-03 15:46:0213669 kNoSSL,
13670 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613671 TestRound(kGetProxy, kServerChallenge, OK),
13672 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113673 {__LINE__,
13674 kProxy,
asankac93076192016-10-03 15:46:0213675 AUTH_NONE,
13676 OK,
13677 kServer,
13678 AUTH_ASYNC,
13679 OK,
13680 2,
13681 kNoSSL,
13682 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513683 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113684 {__LINE__,
13685 kProxy,
asankac93076192016-10-03 15:46:0213686 AUTH_NONE,
13687 OK,
13688 kServer,
13689 AUTH_ASYNC,
13690 ERR_INVALID_AUTH_CREDENTIALS,
13691 2,
13692 kNoSSL,
13693 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613694 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213695 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113696 {__LINE__,
13697 kProxy,
asankac93076192016-10-03 15:46:0213698 AUTH_SYNC,
13699 OK,
13700 kServer,
13701 AUTH_NONE,
13702 OK,
13703 2,
13704 kNoSSL,
13705 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513706 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113707 {__LINE__,
13708 kProxy,
asankac93076192016-10-03 15:46:0213709 AUTH_SYNC,
13710 ERR_INVALID_AUTH_CREDENTIALS,
13711 kServer,
13712 AUTH_NONE,
13713 OK,
13714 2,
13715 kNoSSL,
13716 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613717 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113718 {__LINE__,
13719 kProxy,
asankac93076192016-10-03 15:46:0213720 AUTH_ASYNC,
13721 OK,
13722 kServer,
13723 AUTH_NONE,
13724 OK,
13725 2,
13726 kNoSSL,
13727 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513728 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113729 {__LINE__,
13730 kProxy,
asankac93076192016-10-03 15:46:0213731 AUTH_ASYNC,
13732 ERR_INVALID_AUTH_CREDENTIALS,
13733 kServer,
13734 AUTH_NONE,
13735 OK,
13736 2,
13737 kNoSSL,
13738 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613739 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113740 {__LINE__,
13741 kProxy,
13742 AUTH_ASYNC,
13743 ERR_INVALID_AUTH_CREDENTIALS,
13744 kServer,
13745 AUTH_NONE,
13746 OK,
13747 3,
13748 kNoSSL,
13749 {TestRound(kGetProxy, kProxyChallenge, OK),
13750 TestRound(kGetProxy, kProxyChallenge, OK),
13751 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213752 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113753 {__LINE__,
13754 kProxy,
asankac93076192016-10-03 15:46:0213755 AUTH_SYNC,
13756 OK,
13757 kServer,
13758 AUTH_SYNC,
13759 OK,
13760 3,
13761 kNoSSL,
13762 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513763 TestRound(kGetProxyAuth, kServerChallenge, OK),
13764 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113765 {__LINE__,
13766 kProxy,
asankac93076192016-10-03 15:46:0213767 AUTH_SYNC,
13768 OK,
13769 kServer,
13770 AUTH_SYNC,
13771 ERR_INVALID_AUTH_CREDENTIALS,
13772 3,
13773 kNoSSL,
13774 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513775 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613776 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113777 {__LINE__,
13778 kProxy,
asankac93076192016-10-03 15:46:0213779 AUTH_ASYNC,
13780 OK,
13781 kServer,
13782 AUTH_SYNC,
13783 OK,
13784 3,
13785 kNoSSL,
13786 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513787 TestRound(kGetProxyAuth, kServerChallenge, OK),
13788 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113789 {__LINE__,
13790 kProxy,
asankac93076192016-10-03 15:46:0213791 AUTH_ASYNC,
13792 OK,
13793 kServer,
13794 AUTH_SYNC,
13795 ERR_INVALID_AUTH_CREDENTIALS,
13796 3,
13797 kNoSSL,
13798 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513799 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613800 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113801 {__LINE__,
13802 kProxy,
asankac93076192016-10-03 15:46:0213803 AUTH_SYNC,
13804 OK,
13805 kServer,
13806 AUTH_ASYNC,
13807 OK,
13808 3,
13809 kNoSSL,
13810 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513811 TestRound(kGetProxyAuth, kServerChallenge, OK),
13812 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113813 {__LINE__,
13814 kProxy,
13815 AUTH_SYNC,
13816 ERR_INVALID_AUTH_CREDENTIALS,
13817 kServer,
13818 AUTH_ASYNC,
13819 OK,
13820 4,
13821 kNoSSL,
13822 {TestRound(kGetProxy, kProxyChallenge, OK),
13823 TestRound(kGetProxy, kProxyChallenge, OK),
13824 TestRound(kGetProxyAuth, kServerChallenge, OK),
13825 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
13826 {__LINE__,
13827 kProxy,
asankac93076192016-10-03 15:46:0213828 AUTH_SYNC,
13829 OK,
13830 kServer,
13831 AUTH_ASYNC,
13832 ERR_INVALID_AUTH_CREDENTIALS,
13833 3,
13834 kNoSSL,
13835 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513836 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613837 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113838 {__LINE__,
13839 kProxy,
asankac93076192016-10-03 15:46:0213840 AUTH_ASYNC,
13841 OK,
13842 kServer,
13843 AUTH_ASYNC,
13844 OK,
13845 3,
13846 kNoSSL,
13847 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513848 TestRound(kGetProxyAuth, kServerChallenge, OK),
13849 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113850 {__LINE__,
13851 kProxy,
asankac93076192016-10-03 15:46:0213852 AUTH_ASYNC,
13853 OK,
13854 kServer,
13855 AUTH_ASYNC,
13856 ERR_INVALID_AUTH_CREDENTIALS,
13857 3,
13858 kNoSSL,
13859 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513860 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613861 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113862 {__LINE__,
13863 kProxy,
13864 AUTH_ASYNC,
13865 ERR_INVALID_AUTH_CREDENTIALS,
13866 kServer,
13867 AUTH_ASYNC,
13868 ERR_INVALID_AUTH_CREDENTIALS,
13869 4,
13870 kNoSSL,
13871 {TestRound(kGetProxy, kProxyChallenge, OK),
13872 TestRound(kGetProxy, kProxyChallenge, OK),
13873 TestRound(kGetProxyAuth, kServerChallenge, OK),
13874 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213875 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113876 {__LINE__,
13877 nullptr,
asankac93076192016-10-03 15:46:0213878 AUTH_NONE,
13879 OK,
13880 kSecureServer,
13881 AUTH_NONE,
13882 OK,
13883 1,
13884 0,
13885 {TestRound(kGet, kSuccess, OK)}},
13886 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113887 {__LINE__,
13888 nullptr,
asankac93076192016-10-03 15:46:0213889 AUTH_NONE,
13890 OK,
13891 kSecureServer,
13892 AUTH_SYNC,
13893 OK,
13894 2,
13895 0,
13896 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513897 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113898 {__LINE__,
13899 nullptr,
asankac93076192016-10-03 15:46:0213900 AUTH_NONE,
13901 OK,
13902 kSecureServer,
13903 AUTH_SYNC,
13904 ERR_INVALID_AUTH_CREDENTIALS,
13905 2,
13906 0,
asankae2257db2016-10-11 22:03:1613907 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113908 {__LINE__,
13909 nullptr,
asankac93076192016-10-03 15:46:0213910 AUTH_NONE,
13911 OK,
13912 kSecureServer,
13913 AUTH_ASYNC,
13914 OK,
13915 2,
13916 0,
13917 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513918 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113919 {__LINE__,
13920 nullptr,
asankac93076192016-10-03 15:46:0213921 AUTH_NONE,
13922 OK,
13923 kSecureServer,
13924 AUTH_ASYNC,
13925 ERR_INVALID_AUTH_CREDENTIALS,
13926 2,
13927 0,
asankae2257db2016-10-11 22:03:1613928 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213929 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113930 {__LINE__,
13931 kProxy,
asankac93076192016-10-03 15:46:0213932 AUTH_NONE,
13933 OK,
13934 kSecureServer,
13935 AUTH_NONE,
13936 OK,
13937 1,
13938 0,
13939 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13940 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113941 {__LINE__,
13942 kProxy,
asankac93076192016-10-03 15:46:0213943 AUTH_NONE,
13944 OK,
13945 kSecureServer,
13946 AUTH_SYNC,
13947 OK,
13948 2,
13949 0,
13950 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513951 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113952 {__LINE__,
13953 kProxy,
asankac93076192016-10-03 15:46:0213954 AUTH_NONE,
13955 OK,
13956 kSecureServer,
13957 AUTH_SYNC,
13958 ERR_INVALID_AUTH_CREDENTIALS,
13959 2,
13960 0,
13961 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613962 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113963 {__LINE__,
13964 kProxy,
asankac93076192016-10-03 15:46:0213965 AUTH_NONE,
13966 OK,
13967 kSecureServer,
13968 AUTH_ASYNC,
13969 OK,
13970 2,
13971 0,
13972 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513973 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113974 {__LINE__,
13975 kProxy,
asankac93076192016-10-03 15:46:0213976 AUTH_NONE,
13977 OK,
13978 kSecureServer,
13979 AUTH_ASYNC,
13980 ERR_INVALID_AUTH_CREDENTIALS,
13981 2,
13982 0,
13983 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613984 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213985 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113986 {__LINE__,
13987 kProxy,
asankac93076192016-10-03 15:46:0213988 AUTH_SYNC,
13989 OK,
13990 kSecureServer,
13991 AUTH_NONE,
13992 OK,
13993 2,
13994 1,
13995 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513996 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113997 {__LINE__,
13998 kProxy,
asankac93076192016-10-03 15:46:0213999 AUTH_SYNC,
14000 ERR_INVALID_AUTH_CREDENTIALS,
14001 kSecureServer,
14002 AUTH_NONE,
14003 OK,
14004 2,
14005 kNoSSL,
14006 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1614007 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114008 {__LINE__,
14009 kProxy,
asankae2257db2016-10-11 22:03:1614010 AUTH_SYNC,
14011 ERR_UNSUPPORTED_AUTH_SCHEME,
14012 kSecureServer,
14013 AUTH_NONE,
14014 OK,
14015 2,
14016 kNoSSL,
14017 {TestRound(kConnect, kProxyChallenge, OK),
14018 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114019 {__LINE__,
14020 kProxy,
asankae2257db2016-10-11 22:03:1614021 AUTH_SYNC,
14022 ERR_UNEXPECTED,
14023 kSecureServer,
14024 AUTH_NONE,
14025 OK,
14026 2,
14027 kNoSSL,
14028 {TestRound(kConnect, kProxyChallenge, OK),
14029 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3114030 {__LINE__,
14031 kProxy,
asankac93076192016-10-03 15:46:0214032 AUTH_ASYNC,
14033 OK,
14034 kSecureServer,
14035 AUTH_NONE,
14036 OK,
14037 2,
14038 1,
14039 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1514040 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114041 {__LINE__,
14042 kProxy,
asankac93076192016-10-03 15:46:0214043 AUTH_ASYNC,
14044 ERR_INVALID_AUTH_CREDENTIALS,
14045 kSecureServer,
14046 AUTH_NONE,
14047 OK,
14048 2,
14049 kNoSSL,
14050 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1614051 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0214052 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3114053 {__LINE__,
14054 kProxy,
asankac93076192016-10-03 15:46:0214055 AUTH_SYNC,
14056 OK,
14057 kSecureServer,
14058 AUTH_SYNC,
14059 OK,
14060 3,
14061 1,
14062 {TestRound(kConnect, kProxyChallenge, OK),
14063 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14064 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514065 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114066 {__LINE__,
14067 kProxy,
asankac93076192016-10-03 15:46:0214068 AUTH_SYNC,
14069 OK,
14070 kSecureServer,
14071 AUTH_SYNC,
14072 ERR_INVALID_AUTH_CREDENTIALS,
14073 3,
14074 1,
14075 {TestRound(kConnect, kProxyChallenge, OK),
14076 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14077 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614078 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114079 {__LINE__,
14080 kProxy,
asankac93076192016-10-03 15:46:0214081 AUTH_ASYNC,
14082 OK,
14083 kSecureServer,
14084 AUTH_SYNC,
14085 OK,
14086 3,
14087 1,
14088 {TestRound(kConnect, kProxyChallenge, OK),
14089 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14090 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514091 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114092 {__LINE__,
14093 kProxy,
asankac93076192016-10-03 15:46:0214094 AUTH_ASYNC,
14095 OK,
14096 kSecureServer,
14097 AUTH_SYNC,
14098 ERR_INVALID_AUTH_CREDENTIALS,
14099 3,
14100 1,
14101 {TestRound(kConnect, kProxyChallenge, OK),
14102 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14103 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614104 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114105 {__LINE__,
14106 kProxy,
asankac93076192016-10-03 15:46:0214107 AUTH_SYNC,
14108 OK,
14109 kSecureServer,
14110 AUTH_ASYNC,
14111 OK,
14112 3,
14113 1,
14114 {TestRound(kConnect, kProxyChallenge, OK),
14115 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14116 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514117 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114118 {__LINE__,
14119 kProxy,
asankac93076192016-10-03 15:46:0214120 AUTH_SYNC,
14121 OK,
14122 kSecureServer,
14123 AUTH_ASYNC,
14124 ERR_INVALID_AUTH_CREDENTIALS,
14125 3,
14126 1,
14127 {TestRound(kConnect, kProxyChallenge, OK),
14128 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14129 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614130 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114131 {__LINE__,
14132 kProxy,
asankac93076192016-10-03 15:46:0214133 AUTH_ASYNC,
14134 OK,
14135 kSecureServer,
14136 AUTH_ASYNC,
14137 OK,
14138 3,
14139 1,
14140 {TestRound(kConnect, kProxyChallenge, OK),
14141 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14142 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514143 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114144 {__LINE__,
14145 kProxy,
asankac93076192016-10-03 15:46:0214146 AUTH_ASYNC,
14147 OK,
14148 kSecureServer,
14149 AUTH_ASYNC,
14150 ERR_INVALID_AUTH_CREDENTIALS,
14151 3,
14152 1,
14153 {TestRound(kConnect, kProxyChallenge, OK),
14154 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14155 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614156 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114157 {__LINE__,
14158 kProxy,
14159 AUTH_ASYNC,
14160 ERR_INVALID_AUTH_CREDENTIALS,
14161 kSecureServer,
14162 AUTH_ASYNC,
14163 ERR_INVALID_AUTH_CREDENTIALS,
14164 4,
14165 2,
14166 {TestRound(kConnect, kProxyChallenge, OK),
14167 TestRound(kConnect, kProxyChallenge, OK),
14168 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14169 &kServerChallenge),
14170 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1514171 };
14172
asanka463ca4262016-11-16 02:34:3114173 for (const auto& test_config : test_configs) {
14174 SCOPED_TRACE(::testing::Message() << "Test config at "
14175 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0814176 HttpAuthHandlerMock::Factory* auth_factory(
14177 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714178 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4914179 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2614180
14181 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1514182 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3114183 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0814184 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14185 std::string auth_challenge = "Mock realm=proxy";
14186 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2414187 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14188 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0814189 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2014190 empty_ssl_info, origin,
14191 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814192 auth_handler->SetGenerateExpectation(
14193 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114194 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0814195 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
14196 }
[email protected]044de0642010-06-17 10:42:1514197 }
14198 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0014199 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1514200 std::string auth_challenge = "Mock realm=server";
14201 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2414202 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14203 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1514204 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014205 empty_ssl_info, origin,
14206 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514207 auth_handler->SetGenerateExpectation(
14208 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114209 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0814210 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1614211
14212 // The second handler always succeeds. It should only be used where there
14213 // are multiple auth sessions for server auth in the same network
14214 // transaction using the same auth scheme.
14215 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1914216 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1614217 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
14218 empty_ssl_info, origin,
14219 NetLogWithSource());
14220 second_handler->SetGenerateExpectation(true, OK);
14221 auth_factory->AddMockHandler(second_handler.release(),
14222 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1514223 }
14224 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5914225 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914226 ProxyResolutionService::CreateFixed(test_config.proxy_url,
14227 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514228 } else {
Bence Béky53a5aef2018-03-29 21:54:1214229 session_deps_.proxy_resolution_service =
14230 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1514231 }
14232
14233 HttpRequestInfo request;
14234 request.method = "GET";
14235 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e62018-02-07 07:41:1014236 request.traffic_annotation =
14237 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514238
danakj1fd259a02016-04-16 03:17:0914239 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1514240
rchcb68dc62015-05-21 04:45:3614241 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
14242
14243 std::vector<std::vector<MockRead>> mock_reads(1);
14244 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1514245 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214246 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1514247 const TestRound& read_write_round = test_config.rounds[round];
14248
14249 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3614250 mock_reads.back().push_back(read_write_round.read);
14251 mock_writes.back().push_back(read_write_round.write);
14252
14253 // kProxyChallenge uses Proxy-Connection: close which means that the
14254 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5414255 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3614256 mock_reads.push_back(std::vector<MockRead>());
14257 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1514258 }
14259
rchcb68dc62015-05-21 04:45:3614260 if (read_write_round.extra_read) {
14261 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1514262 }
rchcb68dc62015-05-21 04:45:3614263 if (read_write_round.extra_write) {
14264 mock_writes.back().push_back(*read_write_round.extra_write);
14265 }
[email protected]044de0642010-06-17 10:42:1514266
14267 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1514268 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0714269 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1514270 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3614271 }
[email protected]044de0642010-06-17 10:42:1514272
danakj1fd259a02016-04-16 03:17:0914273 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3614274 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1914275 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:0114276 mock_reads[i], mock_writes[i]));
rchcb68dc62015-05-21 04:45:3614277 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3214278 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3614279 }
14280
mmenkecc2298e2015-12-07 18:20:1814281 // Transaction must be created after DataProviders, so it's destroyed before
14282 // they are as well.
14283 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14284
rchcb68dc62015-05-21 04:45:3614285 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214286 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3614287 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1514288 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4114289 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1514290 int rv;
14291 if (round == 0) {
tfarina42834112016-09-22 13:38:2014292 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514293 } else {
[email protected]49639fa2011-12-20 23:22:4114294 rv = trans.RestartWithAuth(
14295 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1514296 }
14297 if (rv == ERR_IO_PENDING)
14298 rv = callback.WaitForResult();
14299
14300 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1614301 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5014302 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5514303 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1514304 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
14305 continue;
14306 }
14307 if (round + 1 < test_config.num_auth_rounds) {
Emily Starkf2c9bbd2019-04-09 17:08:5814308 EXPECT_TRUE(response->auth_challenge.has_value());
[email protected]044de0642010-06-17 10:42:1514309 } else {
Emily Starkf2c9bbd2019-04-09 17:08:5814310 EXPECT_FALSE(response->auth_challenge.has_value());
asankae2257db2016-10-11 22:03:1614311 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1514312 }
14313 }
[email protected]e5ae96a2010-04-14 20:12:4514314 }
14315}
14316
bncd16676a2016-07-20 16:23:0114317TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1414318 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1414319 HttpAuthHandlerMock::Factory* auth_factory(
14320 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714321 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1214322 session_deps_.proxy_resolution_service =
14323 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0714324 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
[email protected]c871bce92010-07-15 21:51:1414325
14326 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14327 auth_handler->set_connection_based(true);
14328 std::string auth_challenge = "Mock realm=server";
14329 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2414330 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14331 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4914332 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1414333 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014334 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814335 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1414336
[email protected]c871bce92010-07-15 21:51:1414337 int rv = OK;
Raul Tambre94493c652019-03-11 17:18:3514338 const HttpResponseInfo* response = nullptr;
[email protected]c871bce92010-07-15 21:51:1414339 HttpRequestInfo request;
14340 request.method = "GET";
14341 request.url = origin;
Ramin Halavatib5e433e62018-02-07 07:41:1014342 request.traffic_annotation =
14343 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714344
danakj1fd259a02016-04-16 03:17:0914345 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1014346
14347 // Use a TCP Socket Pool with only one connection per group. This is used
14348 // to validate that the TCP socket is not released to the pool between
14349 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4214350 HttpNetworkSessionPeer session_peer(session.get());
Matt Menked6fd2a52019-03-20 06:14:3614351 CommonConnectJobParams common_connect_job_params(
14352 session->CreateCommonConnectJobParams());
[email protected]ab739042011-04-07 15:22:2814353 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
Tarun Bansala7635092019-02-20 10:00:5914354 50, // Max sockets for pool
14355 1, // Max sockets per group
14356 base::TimeDelta::FromSeconds(10), // unused_idle_socket_timeout
Matt Menked6fd2a52019-03-20 06:14:3614357 &common_connect_job_params, session_deps_.ssl_config_service.get());
Jeremy Roman0579ed62017-08-29 15:56:1914358 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4014359 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
14360 base::WrapUnique(transport_pool));
dchengc7eeda422015-12-26 03:56:4814361 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1014362
bnc691fda62016-08-12 00:43:1614363 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114364 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1414365
14366 const MockWrite kGet(
14367 "GET / HTTP/1.1\r\n"
14368 "Host: www.example.com\r\n"
14369 "Connection: keep-alive\r\n\r\n");
14370 const MockWrite kGetAuth(
14371 "GET / HTTP/1.1\r\n"
14372 "Host: www.example.com\r\n"
14373 "Connection: keep-alive\r\n"
14374 "Authorization: auth_token\r\n\r\n");
14375
14376 const MockRead kServerChallenge(
14377 "HTTP/1.1 401 Unauthorized\r\n"
14378 "WWW-Authenticate: Mock realm=server\r\n"
14379 "Content-Type: text/html; charset=iso-8859-1\r\n"
14380 "Content-Length: 14\r\n\r\n"
14381 "Unauthorized\r\n");
14382 const MockRead kSuccess(
14383 "HTTP/1.1 200 OK\r\n"
14384 "Content-Type: text/html; charset=iso-8859-1\r\n"
14385 "Content-Length: 3\r\n\r\n"
14386 "Yes");
14387
14388 MockWrite writes[] = {
14389 // First round
14390 kGet,
14391 // Second round
14392 kGetAuth,
14393 // Third round
14394 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3014395 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1014396 kGetAuth,
14397 // Competing request
14398 kGet,
[email protected]c871bce92010-07-15 21:51:1414399 };
14400 MockRead reads[] = {
14401 // First round
14402 kServerChallenge,
14403 // Second round
14404 kServerChallenge,
14405 // Third round
[email protected]eca50e122010-09-11 14:03:3014406 kServerChallenge,
14407 // Fourth round
[email protected]c871bce92010-07-15 21:51:1414408 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1014409 // Competing response
14410 kSuccess,
[email protected]c871bce92010-07-15 21:51:1414411 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114412 StaticSocketDataProvider data_provider(reads, writes);
[email protected]bb88e1d32013-05-03 23:11:0714413 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1414414
Matt Menkef6edce752019-03-19 17:21:5614415 const ClientSocketPool::GroupId kSocketGroup(
14416 HostPortPair("www.example.com", 80), ClientSocketPool::SocketType::kHttp,
14417 false /* privacy_mode */);
[email protected]7ef4cbbb2011-02-06 11:19:1014418
14419 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1414420 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2014421 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1414422 if (rv == ERR_IO_PENDING)
14423 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114424 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614425 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214426 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5814427 EXPECT_TRUE(response->auth_challenge.has_value());
Raul Tambre8335a6d2019-02-21 16:57:4314428 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114429 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14430 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414431
[email protected]7ef4cbbb2011-02-06 11:19:1014432 // In between rounds, another request comes in for the same domain.
14433 // It should not be able to grab the TCP socket that trans has already
14434 // claimed.
bnc691fda62016-08-12 00:43:1614435 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114436 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2014437 rv = trans_compete.Start(&request, callback_compete.callback(),
14438 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114439 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1014440 // callback_compete.WaitForResult at this point would stall forever,
14441 // since the HttpNetworkTransaction does not release the request back to
14442 // the pool until after authentication completes.
14443
14444 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1414445 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614446 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414447 if (rv == ERR_IO_PENDING)
14448 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114449 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614450 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214451 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5814452 EXPECT_FALSE(response->auth_challenge.has_value());
Raul Tambre8335a6d2019-02-21 16:57:4314453 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114454 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14455 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414456
[email protected]7ef4cbbb2011-02-06 11:19:1014457 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1414458 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614459 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414460 if (rv == ERR_IO_PENDING)
14461 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114462 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614463 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214464 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5814465 EXPECT_FALSE(response->auth_challenge.has_value());
Raul Tambre8335a6d2019-02-21 16:57:4314466 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114467 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14468 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3014469
[email protected]7ef4cbbb2011-02-06 11:19:1014470 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3014471 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614472 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3014473 if (rv == ERR_IO_PENDING)
14474 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114475 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614476 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214477 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5814478 EXPECT_FALSE(response->auth_challenge.has_value());
Raul Tambre8335a6d2019-02-21 16:57:4314479 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014480
asanka463ca4262016-11-16 02:34:3114481 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
14482 // auth handler should transition to a DONE state in concert with the remote
14483 // server. But that's not something we can test here with a mock handler.
14484 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
14485 auth_handler->state());
14486
[email protected]7ef4cbbb2011-02-06 11:19:1014487 // Read the body since the fourth round was successful. This will also
14488 // release the socket back to the pool.
Victor Costan9c7302b2018-08-27 16:39:4414489 scoped_refptr<IOBufferWithSize> io_buf =
14490 base::MakeRefCounted<IOBufferWithSize>(50);
bnc691fda62016-08-12 00:43:1614491 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014492 if (rv == ERR_IO_PENDING)
14493 rv = callback.WaitForResult();
14494 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614495 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014496 EXPECT_EQ(0, rv);
14497 // There are still 0 idle sockets, since the trans_compete transaction
14498 // will be handed it immediately after trans releases it to the group.
Raul Tambre8335a6d2019-02-21 16:57:4314499 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014500
14501 // The competing request can now finish. Wait for the headers and then
14502 // read the body.
14503 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0114504 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614505 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014506 if (rv == ERR_IO_PENDING)
14507 rv = callback.WaitForResult();
14508 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614509 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014510 EXPECT_EQ(0, rv);
14511
14512 // Finally, the socket is released to the group.
Raul Tambre8335a6d2019-02-21 16:57:4314513 EXPECT_EQ(1u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1414514}
14515
[email protected]65041fa2010-05-21 06:56:5314516// This tests the case that a request is issued via http instead of spdy after
14517// npn is negotiated.
bncd16676a2016-07-20 16:23:0114518TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5314519 HttpRequestInfo request;
14520 request.method = "GET";
bncce36dca22015-04-21 22:11:2314521 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014522 request.traffic_annotation =
14523 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5314524
14525 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314526 MockWrite(
14527 "GET / HTTP/1.1\r\n"
14528 "Host: www.example.org\r\n"
14529 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5314530 };
14531
14532 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5214533 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4314534 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5214535 MockRead("\r\n"),
14536 MockRead("hello world"),
14537 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5314538 };
14539
[email protected]8ddf8322012-02-23 18:08:0614540 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614541 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5314542
[email protected]bb88e1d32013-05-03 23:11:0714543 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5314544
Ryan Sleevib8d7ea02018-05-07 20:01:0114545 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714546 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5314547
[email protected]49639fa2011-12-20 23:22:4114548 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5314549
danakj1fd259a02016-04-16 03:17:0914550 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614551 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5314552
tfarina42834112016-09-22 13:38:2014553 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5314554
robpercival214763f2016-07-01 23:27:0114555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14556 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5314557
bnc691fda62016-08-12 00:43:1614558 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214559 ASSERT_TRUE(response);
14560 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5314561 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14562
14563 std::string response_data;
bnc691fda62016-08-12 00:43:1614564 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5314565 EXPECT_EQ("hello world", response_data);
14566
14567 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214568 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5314569}
[email protected]26ef6582010-06-24 02:30:4714570
bnc55ff9da2015-08-19 18:42:3514571// Simulate the SSL handshake completing with an NPN negotiation followed by an
14572// immediate server closing of the socket.
14573// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0114574TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4714575 HttpRequestInfo request;
14576 request.method = "GET";
bncce36dca22015-04-21 22:11:2314577 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014578 request.traffic_annotation =
14579 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4714580
[email protected]8ddf8322012-02-23 18:08:0614581 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614582 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714583 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4714584
Ryan Hamilton0239aac2018-05-19 00:03:1314585 spdy::SpdySerializedFrame req(
14586 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114587 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4714588
14589 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614590 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4714591 };
14592
Ryan Sleevib8d7ea02018-05-07 20:01:0114593 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714594 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4714595
[email protected]49639fa2011-12-20 23:22:4114596 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4714597
danakj1fd259a02016-04-16 03:17:0914598 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614599 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4714600
tfarina42834112016-09-22 13:38:2014601 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114602 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14603 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4714604}
[email protected]65d34382010-07-01 18:12:2614605
[email protected]795cbf82013-07-22 09:37:2714606// A subclass of HttpAuthHandlerMock that records the request URL when
14607// it gets it. This is needed since the auth handler may get destroyed
14608// before we get a chance to query it.
14609class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
14610 public:
14611 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
14612
Chris Watkins7a41d3552017-12-01 02:13:2714613 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2714614
14615 protected:
dchengb03027d2014-10-21 12:00:2014616 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
14617 const HttpRequestInfo* request,
Bence Béky7236fb72018-08-01 14:35:0914618 CompletionOnceCallback callback,
dchengb03027d2014-10-21 12:00:2014619 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2714620 *url_ = request->url;
14621 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
Bence Béky7236fb72018-08-01 14:35:0914622 credentials, request, std::move(callback), auth_token);
[email protected]795cbf82013-07-22 09:37:2714623 }
14624
14625 private:
14626 GURL* url_;
14627};
14628
[email protected]8e6441ca2010-08-19 05:56:3814629// Test that if we cancel the transaction as the connection is completing, that
14630// everything tears down correctly.
bncd16676a2016-07-20 16:23:0114631TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3814632 // Setup everything about the connection to complete synchronously, so that
14633 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
14634 // for is the callback from the HttpStreamRequest.
14635 // Then cancel the transaction.
14636 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3614637 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3814638 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614639 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
14640 MockRead(SYNCHRONOUS, "hello world"),
14641 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3814642 };
14643
[email protected]8e6441ca2010-08-19 05:56:3814644 HttpRequestInfo request;
14645 request.method = "GET";
bncce36dca22015-04-21 22:11:2314646 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014647 request.traffic_annotation =
14648 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3814649
danakj1fd259a02016-04-16 03:17:0914650 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5814651 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1914652 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2714653
Ryan Sleevib8d7ea02018-05-07 20:01:0114654 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]8e6441ca2010-08-19 05:56:3814655 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0714656 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3814657
[email protected]49639fa2011-12-20 23:22:4114658 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3814659
vishal.b62985ca92015-04-17 08:45:5114660 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4114661 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114662 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3814663 trans.reset(); // Cancel the transaction here.
14664
fdoray92e35a72016-06-10 15:54:5514665 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3014666}
14667
[email protected]ecab6e052014-05-16 14:58:1214668// Test that if a transaction is cancelled after receiving the headers, the
14669// stream is drained properly and added back to the socket pool. The main
14670// purpose of this test is to make sure that an HttpStreamParser can be read
14671// from after the HttpNetworkTransaction and the objects it owns have been
14672// deleted.
14673// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0114674TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1214675 MockRead data_reads[] = {
14676 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
14677 MockRead(ASYNC, "Content-Length: 2\r\n"),
14678 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
14679 MockRead(ASYNC, "1"),
14680 // 2 async reads are necessary to trigger a ReadResponseBody call after the
14681 // HttpNetworkTransaction has been deleted.
14682 MockRead(ASYNC, "2"),
14683 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
14684 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114685 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]ecab6e052014-05-16 14:58:1214686 session_deps_.socket_factory->AddSocketDataProvider(&data);
14687
danakj1fd259a02016-04-16 03:17:0914688 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1214689
14690 {
14691 HttpRequestInfo request;
14692 request.method = "GET";
bncce36dca22015-04-21 22:11:2314693 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014694 request.traffic_annotation =
14695 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1214696
dcheng48459ac22014-08-26 00:46:4114697 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1214698 TestCompletionCallback callback;
14699
tfarina42834112016-09-22 13:38:2014700 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114701 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1214702 callback.WaitForResult();
14703
14704 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214705 ASSERT_TRUE(response);
14706 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1214707 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14708
14709 // The transaction and HttpRequestInfo are deleted.
14710 }
14711
14712 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5514713 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1214714
14715 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4114716 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1214717}
14718
[email protected]76a505b2010-08-25 06:23:0014719// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0114720TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914721 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914722 ProxyResolutionService::CreateFixedFromPacResult(
14723 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114724 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714725 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014727
[email protected]76a505b2010-08-25 06:23:0014728 HttpRequestInfo request;
14729 request.method = "GET";
bncce36dca22015-04-21 22:11:2314730 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014731 request.traffic_annotation =
14732 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014733
14734 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2314735 MockWrite(
14736 "GET http://www.example.org/ HTTP/1.1\r\n"
14737 "Host: www.example.org\r\n"
14738 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014739 };
14740
14741 MockRead data_reads1[] = {
14742 MockRead("HTTP/1.1 200 OK\r\n"),
14743 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14744 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614745 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014746 };
14747
Ryan Sleevib8d7ea02018-05-07 20:01:0114748 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714749 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0014750
[email protected]49639fa2011-12-20 23:22:4114751 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014752
bnc691fda62016-08-12 00:43:1614753 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914754 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614755 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914756 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14757 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014758
bnc691fda62016-08-12 00:43:1614759 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114760 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014761
14762 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114763 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0014764
bnc691fda62016-08-12 00:43:1614765 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214766 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014767
14768 EXPECT_TRUE(response->headers->IsKeepAlive());
14769 EXPECT_EQ(200, response->headers->response_code());
14770 EXPECT_EQ(100, response->headers->GetContentLength());
14771 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714772 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14773 HostPortPair::FromString("myproxy:70")),
14774 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914775 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14776 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14777 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0014778 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2014779
14780 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614781 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014782 TestLoadTimingNotReusedWithPac(load_timing_info,
14783 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0014784}
14785
14786// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0114787TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914788 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914789 ProxyResolutionService::CreateFixedFromPacResult(
14790 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114791 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714792 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914793 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014794
[email protected]76a505b2010-08-25 06:23:0014795 HttpRequestInfo request;
14796 request.method = "GET";
bncce36dca22015-04-21 22:11:2314797 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014798 request.traffic_annotation =
14799 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014800
14801 // Since we have proxy, should try to establish tunnel.
14802 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714803 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14804 "Host: www.example.org:443\r\n"
14805 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014806
rsleevidb16bb02015-11-12 23:47:1714807 MockWrite("GET / HTTP/1.1\r\n"
14808 "Host: www.example.org\r\n"
14809 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014810 };
14811
14812 MockRead data_reads1[] = {
14813 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14814
14815 MockRead("HTTP/1.1 200 OK\r\n"),
14816 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14817 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614818 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014819 };
14820
Ryan Sleevib8d7ea02018-05-07 20:01:0114821 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714822 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614823 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714824 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014825
[email protected]49639fa2011-12-20 23:22:4114826 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014827
bnc691fda62016-08-12 00:43:1614828 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914829 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614830 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914831 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14832 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014833
bnc691fda62016-08-12 00:43:1614834 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114835 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014836
14837 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114838 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4614839 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014840 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014841 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014842 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14843 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014844 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014845 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014846 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14847 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014848
bnc691fda62016-08-12 00:43:1614849 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214850 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014851
14852 EXPECT_TRUE(response->headers->IsKeepAlive());
14853 EXPECT_EQ(200, response->headers->response_code());
14854 EXPECT_EQ(100, response->headers->GetContentLength());
14855 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14856 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714857 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14858 HostPortPair::FromString("myproxy:70")),
14859 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914860 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14861 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14862 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2014863
14864 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614865 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014866 TestLoadTimingNotReusedWithPac(load_timing_info,
14867 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0014868}
14869
rsleevidb16bb02015-11-12 23:47:1714870// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
14871// literal host.
bncd16676a2016-07-20 16:23:0114872TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5914873 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914874 ProxyResolutionService::CreateFixedFromPacResult(
14875 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714876 BoundTestNetLog log;
14877 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914878 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1714879
14880 HttpRequestInfo request;
14881 request.method = "GET";
Eric Romanda790f92018-11-07 19:17:1514882 request.url = GURL("https://[::2]:443/");
Ramin Halavatib5e433e62018-02-07 07:41:1014883 request.traffic_annotation =
14884 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714885
14886 // Since we have proxy, should try to establish tunnel.
14887 MockWrite data_writes1[] = {
Eric Romanda790f92018-11-07 19:17:1514888 MockWrite("CONNECT [::2]:443 HTTP/1.1\r\n"
14889 "Host: [::2]:443\r\n"
rsleevidb16bb02015-11-12 23:47:1714890 "Proxy-Connection: keep-alive\r\n\r\n"),
14891
14892 MockWrite("GET / HTTP/1.1\r\n"
Eric Romanda790f92018-11-07 19:17:1514893 "Host: [::2]\r\n"
rsleevidb16bb02015-11-12 23:47:1714894 "Connection: keep-alive\r\n\r\n"),
14895 };
14896
14897 MockRead data_reads1[] = {
14898 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14899
14900 MockRead("HTTP/1.1 200 OK\r\n"),
14901 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14902 MockRead("Content-Length: 100\r\n\r\n"),
14903 MockRead(SYNCHRONOUS, OK),
14904 };
14905
Ryan Sleevib8d7ea02018-05-07 20:01:0114906 StaticSocketDataProvider data1(data_reads1, data_writes1);
rsleevidb16bb02015-11-12 23:47:1714907 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14908 SSLSocketDataProvider ssl(ASYNC, OK);
14909 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14910
14911 TestCompletionCallback callback1;
14912
bnc691fda62016-08-12 00:43:1614913 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714914
bnc691fda62016-08-12 00:43:1614915 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114916 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714917
14918 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114919 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714920 TestNetLogEntry::List entries;
14921 log.GetEntries(&entries);
14922 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014923 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14924 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714925 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014926 entries, pos,
14927 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14928 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714929
bnc691fda62016-08-12 00:43:1614930 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214931 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714932
14933 EXPECT_TRUE(response->headers->IsKeepAlive());
14934 EXPECT_EQ(200, response->headers->response_code());
14935 EXPECT_EQ(100, response->headers->GetContentLength());
14936 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14937 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714938 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14939 HostPortPair::FromString("myproxy:70")),
14940 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714941
14942 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614943 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714944 TestLoadTimingNotReusedWithPac(load_timing_info,
14945 CONNECT_TIMING_HAS_SSL_TIMES);
14946}
14947
[email protected]76a505b2010-08-25 06:23:0014948// Test a basic HTTPS GET request through a proxy, but the server hangs up
14949// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114950TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4914951 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14952 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114953 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714954 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914955 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014956
[email protected]76a505b2010-08-25 06:23:0014957 HttpRequestInfo request;
14958 request.method = "GET";
bncce36dca22015-04-21 22:11:2314959 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014960 request.traffic_annotation =
14961 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014962
14963 // Since we have proxy, should try to establish tunnel.
14964 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714965 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14966 "Host: www.example.org:443\r\n"
14967 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014968
rsleevidb16bb02015-11-12 23:47:1714969 MockWrite("GET / HTTP/1.1\r\n"
14970 "Host: www.example.org\r\n"
14971 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014972 };
14973
14974 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014975 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614976 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014977 };
14978
Ryan Sleevib8d7ea02018-05-07 20:01:0114979 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714980 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614981 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714982 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014983
[email protected]49639fa2011-12-20 23:22:4114984 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014985
bnc691fda62016-08-12 00:43:1614986 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014987
bnc691fda62016-08-12 00:43:1614988 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114989 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014990
14991 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114992 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614993 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014994 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014995 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014996 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14997 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014998 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014999 entries, pos,
mikecirone8b85c432016-09-08 19:11:0015000 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
15001 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0015002}
15003
[email protected]749eefa82010-09-13 22:14:0315004// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0115005TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
Ryan Hamilton0239aac2018-05-19 00:03:1315006 spdy::SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4915007 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4115008 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0315009
Raul Tambre94493c652019-03-11 17:18:3515010 spdy::SpdySerializedFrame resp(
15011 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315012 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0315013 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115014 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0315015 };
15016
Ryan Sleevib8d7ea02018-05-07 20:01:0115017 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715018 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0315019
[email protected]8ddf8322012-02-23 18:08:0615020 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615021 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715022 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0315023
danakj1fd259a02016-04-16 03:17:0915024 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0315025
15026 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2315027 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4015028 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1115029 PRIVACY_MODE_DISABLED,
15030 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2715031 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5215032 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0315033
15034 HttpRequestInfo request;
15035 request.method = "GET";
bncce36dca22015-04-21 22:11:2315036 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015037 request.traffic_annotation =
15038 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0315039
bnc691fda62016-08-12 00:43:1615040 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0315041
[email protected]41d64e82013-07-03 22:44:2615042 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015043 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115044 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15045 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0315046}
15047
[email protected]73b8dd222010-11-11 19:55:2415048// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1615049// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0215050void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0715051 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2915052 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715053 request_info.url = GURL("https://www.example.com/");
15054 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915055 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015056 request_info.traffic_annotation =
15057 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715058
[email protected]8ddf8322012-02-23 18:08:0615059 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2915060 MockWrite data_writes[] = {
15061 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2415062 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115063 StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
[email protected]bb88e1d32013-05-03 23:11:0715064 session_deps_.socket_factory->AddSocketDataProvider(&data);
15065 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2415066
danakj1fd259a02016-04-16 03:17:0915067 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615068 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2415069
[email protected]49639fa2011-12-20 23:22:4115070 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015071 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2915072 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2415073 rv = callback.WaitForResult();
15074 ASSERT_EQ(error, rv);
15075}
15076
bncd16676a2016-07-20 16:23:0115077TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2415078 // Just check a grab bag of cert errors.
15079 static const int kErrors[] = {
15080 ERR_CERT_COMMON_NAME_INVALID,
15081 ERR_CERT_AUTHORITY_INVALID,
15082 ERR_CERT_DATE_INVALID,
15083 };
Avi Drissman4365a4782018-12-28 19:26:2415084 for (size_t i = 0; i < base::size(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0615085 CheckErrorIsPassedBack(kErrors[i], ASYNC);
15086 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2415087 }
15088}
15089
[email protected]bd0b6772011-01-11 19:59:3015090// Ensure that a client certificate is removed from the SSL client auth
15091// cache when:
15092// 1) No proxy is involved.
15093// 2) TLS False Start is disabled.
15094// 3) The initial TLS handshake requests a client certificate.
15095// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115096TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915097 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715098 request_info.url = GURL("https://www.example.com/");
15099 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915100 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015101 request_info.traffic_annotation =
15102 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715103
[email protected]bd0b6772011-01-11 19:59:3015104 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115105 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015106
15107 // [ssl_]data1 contains the data for the first SSL handshake. When a
15108 // CertificateRequest is received for the first time, the handshake will
15109 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2915110 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015111 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715112 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115113 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715114 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015115
15116 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
15117 // False Start is not being used, the result of the SSL handshake will be
15118 // returned as part of the SSLClientSocket::Connect() call. This test
15119 // matches the result of a server sending a handshake_failure alert,
15120 // rather than a Finished message, because it requires a client
15121 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2915122 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3015123 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715124 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115125 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715126 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015127
15128 // [ssl_]data3 contains the data for the third SSL handshake. When a
15129 // connection to a server fails during an SSL handshake,
Steven Valdez0ef94d02018-11-19 23:28:1315130 // HttpNetworkTransaction will attempt to fallback to TLSv1.2 if the previous
15131 // connection was attempted with TLSv1.3. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3015132 // of the HttpNetworkTransaction. Because this test failure is due to
15133 // requiring a client certificate, this fallback handshake should also
15134 // fail.
ttuttle859dc7a2015-04-23 19:42:2915135 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
Steven Valdez0ef94d02018-11-19 23:28:1315136 ssl_data3.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
[email protected]bd0b6772011-01-11 19:59:3015137 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715138 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115139 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715140 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015141
[email protected]80c75f682012-05-26 16:22:1715142 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
15143 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4215144 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
15145 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1715146 // of the HttpNetworkTransaction. Because this test failure is due to
15147 // requiring a client certificate, this fallback handshake should also
15148 // fail.
ttuttle859dc7a2015-04-23 19:42:2915149 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1715150 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715151 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115152 StaticSocketDataProvider data4;
[email protected]bb88e1d32013-05-03 23:11:0715153 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715154
danakj1fd259a02016-04-16 03:17:0915155 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615156 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015157
[email protected]bd0b6772011-01-11 19:59:3015158 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4115159 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015160 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115161 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015162
15163 // Complete the SSL handshake, which should abort due to requiring a
15164 // client certificate.
15165 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115166 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015167
15168 // Indicate that no certificate should be supplied. From the perspective
15169 // of SSLClientCertCache, NULL is just as meaningful as a real
15170 // certificate, so this is the same as supply a
15171 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515172 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115173 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015174
15175 // Ensure the certificate was added to the client auth cache before
15176 // allowing the connection to continue restarting.
15177 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415178 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115179 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415180 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215181 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015182
15183 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715184 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15185 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015186 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115187 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015188
15189 // Ensure that the client certificate is removed from the cache on a
15190 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115191 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415192 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015193}
15194
15195// Ensure that a client certificate is removed from the SSL client auth
15196// cache when:
15197// 1) No proxy is involved.
15198// 2) TLS False Start is enabled.
15199// 3) The initial TLS handshake requests a client certificate.
15200// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115201TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915202 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715203 request_info.url = GURL("https://www.example.com/");
15204 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915205 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015206 request_info.traffic_annotation =
15207 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715208
[email protected]bd0b6772011-01-11 19:59:3015209 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115210 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015211
15212 // When TLS False Start is used, SSLClientSocket::Connect() calls will
15213 // return successfully after reading up to the peer's Certificate message.
15214 // This is to allow the caller to call SSLClientSocket::Write(), which can
15215 // enqueue application data to be sent in the same packet as the
15216 // ChangeCipherSpec and Finished messages.
15217 // The actual handshake will be finished when SSLClientSocket::Read() is
15218 // called, which expects to process the peer's ChangeCipherSpec and
15219 // Finished messages. If there was an error negotiating with the peer,
15220 // such as due to the peer requiring a client certificate when none was
15221 // supplied, the alert sent by the peer won't be processed until Read() is
15222 // called.
15223
15224 // Like the non-False Start case, when a client certificate is requested by
15225 // the peer, the handshake is aborted during the Connect() call.
15226 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2915227 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015228 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715229 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115230 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715231 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015232
15233 // When a client certificate is supplied, Connect() will not be aborted
15234 // when the peer requests the certificate. Instead, the handshake will
15235 // artificially succeed, allowing the caller to write the HTTP request to
15236 // the socket. The handshake messages are not processed until Read() is
15237 // called, which then detects that the handshake was aborted, due to the
15238 // peer sending a handshake_failure because it requires a client
15239 // certificate.
ttuttle859dc7a2015-04-23 19:42:2915240 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015241 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715242 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2915243 MockRead data2_reads[] = {
15244 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3015245 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115246 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715247 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015248
15249 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1715250 // the data for the SSL handshake once the TLSv1.1 connection falls back to
15251 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915252 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015253 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715254 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115255 StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715256 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015257
[email protected]80c75f682012-05-26 16:22:1715258 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
15259 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915260 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1715261 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715262 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115263 StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715264 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715265
[email protected]7799de12013-05-30 05:52:5115266 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2915267 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5115268 ssl_data5.cert_request_info = cert_request.get();
15269 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
Ryan Sleevib8d7ea02018-05-07 20:01:0115270 StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
[email protected]7799de12013-05-30 05:52:5115271 session_deps_.socket_factory->AddSocketDataProvider(&data5);
15272
danakj1fd259a02016-04-16 03:17:0915273 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615274 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015275
[email protected]bd0b6772011-01-11 19:59:3015276 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4115277 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015278 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115279 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015280
15281 // Complete the SSL handshake, which should abort due to requiring a
15282 // client certificate.
15283 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115284 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015285
15286 // Indicate that no certificate should be supplied. From the perspective
15287 // of SSLClientCertCache, NULL is just as meaningful as a real
15288 // certificate, so this is the same as supply a
15289 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515290 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115291 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015292
15293 // Ensure the certificate was added to the client auth cache before
15294 // allowing the connection to continue restarting.
15295 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415296 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115297 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415298 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215299 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015300
[email protected]bd0b6772011-01-11 19:59:3015301 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715302 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15303 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015304 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115305 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015306
15307 // Ensure that the client certificate is removed from the cache on a
15308 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115309 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415310 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015311}
15312
[email protected]8c405132011-01-11 22:03:1815313// Ensure that a client certificate is removed from the SSL client auth
15314// cache when:
15315// 1) An HTTPS proxy is involved.
15316// 3) The HTTPS proxy requests a client certificate.
15317// 4) The client supplies an invalid/unacceptable certificate for the
15318// proxy.
15319// The test is repeated twice, first for connecting to an HTTPS endpoint,
15320// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0115321TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4915322 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
15323 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115324 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715325 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1815326
15327 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115328 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1815329
15330 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
15331 // [ssl_]data[1-3]. Rather than represending the endpoint
15332 // (www.example.com:443), they represent failures with the HTTPS proxy
15333 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2915334 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1815335 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715336 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115337 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715338 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1815339
ttuttle859dc7a2015-04-23 19:42:2915340 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815341 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715342 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115343 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715344 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1815345
[email protected]80c75f682012-05-26 16:22:1715346 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
15347#if 0
ttuttle859dc7a2015-04-23 19:42:2915348 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1815349 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715350 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115351 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715352 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1715353#endif
[email protected]8c405132011-01-11 22:03:1815354
ttuttle859dc7a2015-04-23 19:42:2915355 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1815356 requests[0].url = GURL("https://www.example.com/");
15357 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915358 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015359 requests[0].traffic_annotation =
15360 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815361
15362 requests[1].url = GURL("http://www.example.com/");
15363 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915364 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015365 requests[1].traffic_annotation =
15366 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815367
Avi Drissman4365a4782018-12-28 19:26:2415368 for (size_t i = 0; i < base::size(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0715369 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0915370 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615371 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1815372
15373 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4115374 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015375 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115376 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815377
15378 // Complete the SSL handshake, which should abort due to requiring a
15379 // client certificate.
15380 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115381 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1815382
15383 // Indicate that no certificate should be supplied. From the perspective
15384 // of SSLClientCertCache, NULL is just as meaningful as a real
15385 // certificate, so this is the same as supply a
15386 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515387 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115388 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1815389
15390 // Ensure the certificate was added to the client auth cache before
15391 // allowing the connection to continue restarting.
15392 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415393 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115394 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415395 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215396 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1815397 // Ensure the certificate was NOT cached for the endpoint. This only
15398 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4115399 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415400 HostPortPair("www.example.com", 443), &client_cert,
15401 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815402
15403 // Restart the handshake. This will consume ssl_data2, which fails, and
15404 // then consume ssl_data3, which should also fail. The result code is
15405 // checked against what ssl_data3 should return.
15406 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115407 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1815408
15409 // Now that the new handshake has failed, ensure that the client
15410 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4115411 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415412 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4115413 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415414 HostPortPair("www.example.com", 443), &client_cert,
15415 &client_private_key));
[email protected]8c405132011-01-11 22:03:1815416 }
15417}
15418
bncd16676a2016-07-20 16:23:0115419TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4615420 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915421 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915422 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615423
bnc032658ba2016-09-26 18:17:1515424 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615425
Ryan Hamilton0239aac2018-05-19 00:03:1315426 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915427 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815428 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315429 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715430 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615431 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115432 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615433 };
Ryan Hamilton0239aac2018-05-19 00:03:1315434 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515435 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315436 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115437 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315438 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515439 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315440 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115441 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615442 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115443 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15444 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315445 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615446 };
15447
eroman36d84e54432016-03-17 03:23:0215448 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215449 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115450 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715451 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615452
[email protected]aa22b242011-11-16 18:58:2915453 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615454 HttpRequestInfo request1;
15455 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315456 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615457 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015458 request1.traffic_annotation =
15459 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015460 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615461
tfarina42834112016-09-22 13:38:2015462 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115463 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15464 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615465
15466 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215467 ASSERT_TRUE(response);
15468 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215469 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615470
15471 std::string response_data;
robpercival214763f2016-07-01 23:27:0115472 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615473 EXPECT_EQ("hello!", response_data);
15474
bnca4d611d2016-09-22 19:55:3715475 // Preload mail.example.com into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315476 rv = session_deps_.host_resolver->LoadIntoCache(
15477 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115478 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615479
15480 HttpRequestInfo request2;
15481 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715482 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615483 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015484 request2.traffic_annotation =
15485 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015486 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615487
tfarina42834112016-09-22 13:38:2015488 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15490 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615491
15492 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215493 ASSERT_TRUE(response);
15494 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215495 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615496 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215497 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115498 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615499 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615500}
15501
bncd16676a2016-07-20 16:23:0115502TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0215503 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915504 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915505 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0215506
bnc032658ba2016-09-26 18:17:1515507 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0215508
Ryan Hamilton0239aac2018-05-19 00:03:1315509 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915510 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815511 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315512 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715513 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0215514 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115515 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0215516 };
Ryan Hamilton0239aac2018-05-19 00:03:1315517 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515518 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315519 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115520 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315521 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515522 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315523 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115524 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0215525 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115526 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15527 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315528 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0215529 };
15530
eroman36d84e54432016-03-17 03:23:0215531 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215532 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115533 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715534 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0215535
15536 TestCompletionCallback callback;
15537 HttpRequestInfo request1;
15538 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315539 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0215540 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015541 request1.traffic_annotation =
15542 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015543 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215544
tfarina42834112016-09-22 13:38:2015545 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115546 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15547 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215548
15549 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215550 ASSERT_TRUE(response);
15551 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215552 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215553
15554 std::string response_data;
robpercival214763f2016-07-01 23:27:0115555 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215556 EXPECT_EQ("hello!", response_data);
15557
15558 HttpRequestInfo request2;
15559 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715560 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0215561 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015562 request2.traffic_annotation =
15563 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015564 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215565
tfarina42834112016-09-22 13:38:2015566 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115567 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15568 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215569
15570 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215571 ASSERT_TRUE(response);
15572 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215573 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215574 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215575 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115576 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215577 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0215578}
15579
bnc8016c1f2017-03-31 02:11:2915580// Regression test for https://crbug.com/546991.
15581// The server might not be able to serve an IP pooled request, and might send a
15582// 421 Misdirected Request response status to indicate this.
15583// HttpNetworkTransaction should reset the request and retry without IP pooling.
15584TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
15585 // Two hosts resolve to the same IP address.
15586 const std::string ip_addr = "1.2.3.4";
15587 IPAddress ip;
15588 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15589 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15590
Jeremy Roman0579ed62017-08-29 15:56:1915591 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2915592 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15593 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15594
15595 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15596
15597 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315598 spdy::SpdySerializedFrame req1(
bnc8016c1f2017-03-31 02:11:2915599 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15600 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315601 spdy::SpdySerializedFrame req2(
bnc8016c1f2017-03-31 02:11:2915602 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315603 spdy::SpdySerializedFrame rst(
15604 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
bnc8016c1f2017-03-31 02:11:2915605 MockWrite writes1[] = {
15606 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15607 CreateMockWrite(rst, 6),
15608 };
15609
15610 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315611 spdy::SpdySerializedFrame resp1(
15612 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15613 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15614 spdy::SpdyHeaderBlock response_headers;
15615 response_headers[spdy::kHttp2StatusHeader] = "421";
15616 spdy::SpdySerializedFrame resp2(
bnc8016c1f2017-03-31 02:11:2915617 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
15618 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15619 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15620
15621 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115622 SequencedSocketData data1(connect1, reads1, writes1);
bnc8016c1f2017-03-31 02:11:2915623 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15624
15625 AddSSLSocketData();
15626
15627 // Retry the second request on a second connection.
15628 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315629 spdy::SpdySerializedFrame req3(
bnc8016c1f2017-03-31 02:11:2915630 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15631 MockWrite writes2[] = {
15632 CreateMockWrite(req3, 0),
15633 };
15634
Ryan Hamilton0239aac2018-05-19 00:03:1315635 spdy::SpdySerializedFrame resp3(
15636 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
15637 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
bnc8016c1f2017-03-31 02:11:2915638 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15639 MockRead(ASYNC, 0, 3)};
15640
15641 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115642 SequencedSocketData data2(connect2, reads2, writes2);
bnc8016c1f2017-03-31 02:11:2915643 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15644
15645 AddSSLSocketData();
15646
15647 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315648 int rv = session_deps_.host_resolver->LoadIntoCache(
15649 HostPortPair("mail.example.com", 443), base::nullopt);
bnc8016c1f2017-03-31 02:11:2915650 EXPECT_THAT(rv, IsOk());
15651
15652 HttpRequestInfo request1;
15653 request1.method = "GET";
15654 request1.url = GURL("https://www.example.org/");
15655 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015656 request1.traffic_annotation =
15657 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915658 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15659
Eric Orthf4db66a2019-02-19 21:35:3315660 TestCompletionCallback callback;
bnc8016c1f2017-03-31 02:11:2915661 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15662 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15663 rv = callback.WaitForResult();
15664 EXPECT_THAT(rv, IsOk());
15665
15666 const HttpResponseInfo* response = trans1.GetResponseInfo();
15667 ASSERT_TRUE(response);
15668 ASSERT_TRUE(response->headers);
15669 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15670 EXPECT_TRUE(response->was_fetched_via_spdy);
15671 EXPECT_TRUE(response->was_alpn_negotiated);
15672 std::string response_data;
15673 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15674 EXPECT_EQ("hello!", response_data);
15675
15676 HttpRequestInfo request2;
15677 request2.method = "GET";
15678 request2.url = GURL("https://mail.example.org/");
15679 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015680 request2.traffic_annotation =
15681 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915682 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15683
15684 BoundTestNetLog log;
15685 rv = trans2.Start(&request2, callback.callback(), log.bound());
15686 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15687 rv = callback.WaitForResult();
15688 EXPECT_THAT(rv, IsOk());
15689
15690 response = trans2.GetResponseInfo();
15691 ASSERT_TRUE(response);
15692 ASSERT_TRUE(response->headers);
15693 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15694 EXPECT_TRUE(response->was_fetched_via_spdy);
15695 EXPECT_TRUE(response->was_alpn_negotiated);
15696 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15697 EXPECT_EQ("hello!", response_data);
15698
15699 TestNetLogEntry::List entries;
15700 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5915701 ExpectLogContainsSomewhere(
15702 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2915703 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5915704}
15705
15706// Test that HTTP 421 responses are properly returned to the caller if received
15707// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
15708// portions of the response.
15709TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
15710 // Two hosts resolve to the same IP address.
15711 const std::string ip_addr = "1.2.3.4";
15712 IPAddress ip;
15713 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15714 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15715
Jeremy Roman0579ed62017-08-29 15:56:1915716 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5915717 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15718 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15719
15720 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15721
15722 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315723 spdy::SpdySerializedFrame req1(
davidbence688ae2017-05-04 15:12:5915724 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15725 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315726 spdy::SpdySerializedFrame req2(
davidbence688ae2017-05-04 15:12:5915727 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315728 spdy::SpdySerializedFrame rst(
15729 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
davidbence688ae2017-05-04 15:12:5915730 MockWrite writes1[] = {
15731 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15732 CreateMockWrite(rst, 6),
15733 };
15734
15735 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315736 spdy::SpdySerializedFrame resp1(
15737 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15738 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15739 spdy::SpdyHeaderBlock response_headers;
15740 response_headers[spdy::kHttp2StatusHeader] = "421";
15741 spdy::SpdySerializedFrame resp2(
davidbence688ae2017-05-04 15:12:5915742 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
15743 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15744 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15745
15746 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115747 SequencedSocketData data1(connect1, reads1, writes1);
davidbence688ae2017-05-04 15:12:5915748 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15749
15750 AddSSLSocketData();
15751
15752 // Retry the second request on a second connection. It returns 421 Misdirected
15753 // Retry again.
15754 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315755 spdy::SpdySerializedFrame req3(
davidbence688ae2017-05-04 15:12:5915756 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15757 MockWrite writes2[] = {
15758 CreateMockWrite(req3, 0),
15759 };
15760
Ryan Hamilton0239aac2018-05-19 00:03:1315761 spdy::SpdySerializedFrame resp3(
davidbence688ae2017-05-04 15:12:5915762 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
Ryan Hamilton0239aac2018-05-19 00:03:1315763 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
davidbence688ae2017-05-04 15:12:5915764 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15765 MockRead(ASYNC, 0, 3)};
15766
15767 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115768 SequencedSocketData data2(connect2, reads2, writes2);
davidbence688ae2017-05-04 15:12:5915769 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15770
15771 AddSSLSocketData();
15772
15773 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315774 int rv = session_deps_.host_resolver->LoadIntoCache(
15775 HostPortPair("mail.example.com", 443), base::nullopt);
davidbence688ae2017-05-04 15:12:5915776 EXPECT_THAT(rv, IsOk());
15777
15778 HttpRequestInfo request1;
15779 request1.method = "GET";
15780 request1.url = GURL("https://www.example.org/");
15781 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015782 request1.traffic_annotation =
15783 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915784 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15785
Eric Orthf4db66a2019-02-19 21:35:3315786 TestCompletionCallback callback;
davidbence688ae2017-05-04 15:12:5915787 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15788 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15789 rv = callback.WaitForResult();
15790 EXPECT_THAT(rv, IsOk());
15791
15792 const HttpResponseInfo* response = trans1.GetResponseInfo();
15793 ASSERT_TRUE(response);
15794 ASSERT_TRUE(response->headers);
15795 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15796 EXPECT_TRUE(response->was_fetched_via_spdy);
15797 EXPECT_TRUE(response->was_alpn_negotiated);
15798 std::string response_data;
15799 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15800 EXPECT_EQ("hello!", response_data);
15801
15802 HttpRequestInfo request2;
15803 request2.method = "GET";
15804 request2.url = GURL("https://mail.example.org/");
15805 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015806 request2.traffic_annotation =
15807 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915808 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15809
15810 BoundTestNetLog log;
15811 rv = trans2.Start(&request2, callback.callback(), log.bound());
15812 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15813 rv = callback.WaitForResult();
15814 EXPECT_THAT(rv, IsOk());
15815
15816 // After a retry, the 421 Misdirected Request is reported back up to the
15817 // caller.
15818 response = trans2.GetResponseInfo();
15819 ASSERT_TRUE(response);
15820 ASSERT_TRUE(response->headers);
15821 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
15822 EXPECT_TRUE(response->was_fetched_via_spdy);
15823 EXPECT_TRUE(response->was_alpn_negotiated);
15824 EXPECT_TRUE(response->ssl_info.cert);
15825 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15826 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2915827}
15828
bncd16676a2016-07-20 16:23:0115829TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1315830 UseIPConnectionPoolingWithHostCacheExpiration) {
Eric Orth1da75de2019-02-20 21:10:3415831 // Set up HostResolver to invalidate cached entries after 1 cached resolve.
15832 session_deps_.host_resolver =
15833 std::make_unique<MockCachingHostResolver>(1 /* cache_invalidation_num */);
danakj1fd259a02016-04-16 03:17:0915834 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615835
bnc032658ba2016-09-26 18:17:1515836 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615837
Ryan Hamilton0239aac2018-05-19 00:03:1315838 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915839 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815840 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315841 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715842 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615843 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115844 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615845 };
Ryan Hamilton0239aac2018-05-19 00:03:1315846 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515847 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315848 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115849 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315850 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515851 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315852 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115853 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615854 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115855 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15856 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315857 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615858 };
15859
eroman36d84e54432016-03-17 03:23:0215860 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215861 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115862 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715863 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615864
[email protected]aa22b242011-11-16 18:58:2915865 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615866 HttpRequestInfo request1;
15867 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315868 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615869 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015870 request1.traffic_annotation =
15871 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015872 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615873
tfarina42834112016-09-22 13:38:2015874 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115875 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15876 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615877
15878 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215879 ASSERT_TRUE(response);
15880 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215881 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615882
15883 std::string response_data;
robpercival214763f2016-07-01 23:27:0115884 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615885 EXPECT_EQ("hello!", response_data);
15886
15887 // Preload cache entries into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315888 rv = session_deps_.host_resolver->LoadIntoCache(
15889 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115890 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615891
15892 HttpRequestInfo request2;
15893 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715894 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615895 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015896 request2.traffic_annotation =
15897 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015898 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615899
tfarina42834112016-09-22 13:38:2015900 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115901 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15902 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615903
15904 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215905 ASSERT_TRUE(response);
15906 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215907 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615908 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215909 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115910 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615911 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615912}
15913
bncd16676a2016-07-20 16:23:0115914TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315915 const std::string https_url = "https://www.example.org:8080/";
15916 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415917
15918 // SPDY GET for HTTPS URL
Ryan Hamilton0239aac2018-05-19 00:03:1315919 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915920 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415921
15922 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115923 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415924 };
15925
Raul Tambre94493c652019-03-11 17:18:3515926 spdy::SpdySerializedFrame resp1(
15927 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315928 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4115929 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915930 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415931
Ryan Sleevib8d7ea02018-05-07 20:01:0115932 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415933 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715934 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415935
15936 // HTTP GET for the HTTP URL
15937 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315938 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415939 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315940 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415941 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415942 };
15943
15944 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315945 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15946 MockRead(ASYNC, 2, "hello"),
15947 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415948 };
15949
Ryan Sleevib8d7ea02018-05-07 20:01:0115950 SequencedSocketData data2(reads2, writes2);
[email protected]8450d722012-07-02 19:14:0415951
[email protected]8450d722012-07-02 19:14:0415952 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615953 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715954 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15955 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15956 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415957
danakj1fd259a02016-04-16 03:17:0915958 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415959
15960 // Start the first transaction to set up the SpdySession
15961 HttpRequestInfo request1;
15962 request1.method = "GET";
15963 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415964 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015965 request1.traffic_annotation =
15966 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015967 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415968 TestCompletionCallback callback1;
15969 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015970 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515971 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415972
robpercival214763f2016-07-01 23:27:0115973 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415974 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15975
15976 // Now, start the HTTP request
15977 HttpRequestInfo request2;
15978 request2.method = "GET";
15979 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415980 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015981 request2.traffic_annotation =
15982 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015983 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415984 TestCompletionCallback callback2;
15985 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015986 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515987 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415988
robpercival214763f2016-07-01 23:27:0115989 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415990 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15991}
15992
bnc5452e2a2015-05-08 16:27:4215993// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15994// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115995TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515996 url::SchemeHostPort server("https", "www.example.org", 443);
15997 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215998
bnc8bef8da22016-05-30 01:28:2515999 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4216000 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616001 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216002 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16003
16004 // No data should be read from the alternative, because HTTP/1.1 is
16005 // negotiated.
16006 StaticSocketDataProvider data;
16007 session_deps_.socket_factory->AddSocketDataProvider(&data);
16008
16009 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4616010 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4216011 // mocked. This way the request relies on the alternate Job.
16012 StaticSocketDataProvider data_refused;
16013 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16014 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16015
zhongyi3d4a55e72016-04-22 20:36:4616016 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916017 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016018 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216019 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116020 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216021 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116022 http_server_properties->SetHttp2AlternativeService(
16023 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216024
bnc5452e2a2015-05-08 16:27:4216025 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4616026 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216027 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2516028 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e62018-02-07 07:41:1016029 request.traffic_annotation =
16030 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216031 TestCompletionCallback callback;
16032
16033 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5216034 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2016035 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5216036 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4216037}
16038
bnc40448a532015-05-11 19:13:1416039// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4616040// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1416041// succeeds, the request should succeed, even if the latter fails because
16042// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0116043TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2516044 url::SchemeHostPort server("https", "www.example.org", 443);
16045 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1416046
16047 // Negotiate HTTP/1.1 with alternative.
16048 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616049 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416050 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
16051
16052 // No data should be read from the alternative, because HTTP/1.1 is
16053 // negotiated.
16054 StaticSocketDataProvider data;
16055 session_deps_.socket_factory->AddSocketDataProvider(&data);
16056
zhongyi3d4a55e72016-04-22 20:36:4616057 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1416058 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616059 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416060 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
16061
16062 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2516063 MockWrite("GET / HTTP/1.1\r\n"
16064 "Host: www.example.org\r\n"
16065 "Connection: keep-alive\r\n\r\n"),
16066 MockWrite("GET /second HTTP/1.1\r\n"
16067 "Host: www.example.org\r\n"
16068 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1416069 };
16070
16071 MockRead http_reads[] = {
16072 MockRead("HTTP/1.1 200 OK\r\n"),
16073 MockRead("Content-Type: text/html\r\n"),
16074 MockRead("Content-Length: 6\r\n\r\n"),
16075 MockRead("foobar"),
16076 MockRead("HTTP/1.1 200 OK\r\n"),
16077 MockRead("Content-Type: text/html\r\n"),
16078 MockRead("Content-Length: 7\r\n\r\n"),
16079 MockRead("another"),
16080 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116081 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc40448a532015-05-11 19:13:1416082 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16083
zhongyi3d4a55e72016-04-22 20:36:4616084 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916085 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016086 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1416087 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116088 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216089 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116090 http_server_properties->SetHttp2AlternativeService(
16091 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1416092
16093 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
16094 HttpRequestInfo request1;
16095 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2516096 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1416097 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016098 request1.traffic_annotation =
16099 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416100 TestCompletionCallback callback1;
16101
tfarina42834112016-09-22 13:38:2016102 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416103 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116104 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416105
16106 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5216107 ASSERT_TRUE(response1);
16108 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1416109 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
16110
16111 std::string response_data1;
robpercival214763f2016-07-01 23:27:0116112 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1416113 EXPECT_EQ("foobar", response_data1);
16114
16115 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
16116 // for alternative service.
16117 EXPECT_TRUE(
16118 http_server_properties->IsAlternativeServiceBroken(alternative_service));
16119
zhongyi3d4a55e72016-04-22 20:36:4616120 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1416121 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4616122 // to server.
bnc40448a532015-05-11 19:13:1416123 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
16124 HttpRequestInfo request2;
16125 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2516126 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1416127 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016128 request2.traffic_annotation =
16129 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416130 TestCompletionCallback callback2;
16131
tfarina42834112016-09-22 13:38:2016132 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416133 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116134 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416135
16136 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216137 ASSERT_TRUE(response2);
16138 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1416139 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
16140
16141 std::string response_data2;
robpercival214763f2016-07-01 23:27:0116142 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1416143 EXPECT_EQ("another", response_data2);
16144}
16145
bnc5452e2a2015-05-08 16:27:4216146// Alternative service requires HTTP/2 (or SPDY), but there is already a
16147// HTTP/1.1 socket open to the alternative server. That socket should not be
16148// used.
bncd16676a2016-07-20 16:23:0116149TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4616150 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4216151 HostPortPair alternative("alternative.example.org", 443);
16152 std::string origin_url = "https://origin.example.org:443";
16153 std::string alternative_url = "https://alternative.example.org:443";
16154
16155 // Negotiate HTTP/1.1 with alternative.example.org.
16156 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616157 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216158 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16159
16160 // HTTP/1.1 data for |request1| and |request2|.
16161 MockWrite http_writes[] = {
16162 MockWrite(
16163 "GET / HTTP/1.1\r\n"
16164 "Host: alternative.example.org\r\n"
16165 "Connection: keep-alive\r\n\r\n"),
16166 MockWrite(
16167 "GET / HTTP/1.1\r\n"
16168 "Host: alternative.example.org\r\n"
16169 "Connection: keep-alive\r\n\r\n"),
16170 };
16171
16172 MockRead http_reads[] = {
16173 MockRead(
16174 "HTTP/1.1 200 OK\r\n"
16175 "Content-Type: text/html; charset=iso-8859-1\r\n"
16176 "Content-Length: 40\r\n\r\n"
16177 "first HTTP/1.1 response from alternative"),
16178 MockRead(
16179 "HTTP/1.1 200 OK\r\n"
16180 "Content-Type: text/html; charset=iso-8859-1\r\n"
16181 "Content-Length: 41\r\n\r\n"
16182 "second HTTP/1.1 response from alternative"),
16183 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116184 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc5452e2a2015-05-08 16:27:4216185 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16186
16187 // This test documents that an alternate Job should not pool to an already
16188 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4616189 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4216190 StaticSocketDataProvider data_refused;
16191 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16192 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16193
zhongyi3d4a55e72016-04-22 20:36:4616194 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916195 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016196 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216197 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116198 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216199 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116200 http_server_properties->SetHttp2AlternativeService(
16201 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216202
16203 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4216204 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4616205 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216206 request1.method = "GET";
16207 request1.url = GURL(alternative_url);
16208 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016209 request1.traffic_annotation =
16210 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216211 TestCompletionCallback callback1;
16212
tfarina42834112016-09-22 13:38:2016213 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116214 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616215 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216216 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5216217 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4216218 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216219 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216220 EXPECT_FALSE(response1->was_fetched_via_spdy);
16221 std::string response_data1;
bnc691fda62016-08-12 00:43:1616222 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4216223 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
16224
16225 // Request for origin.example.org, which has an alternative service. This
16226 // will start two Jobs: the alternative looks for connections to pool to,
16227 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4616228 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4216229 // this request fails.
bnc5452e2a2015-05-08 16:27:4216230 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4616231 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216232 request2.method = "GET";
16233 request2.url = GURL(origin_url);
16234 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016235 request2.traffic_annotation =
16236 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216237 TestCompletionCallback callback2;
16238
tfarina42834112016-09-22 13:38:2016239 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116240 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4216241
16242 // Another transaction to alternative. This is to test that the HTTP/1.1
16243 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4216244 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4616245 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216246 request3.method = "GET";
16247 request3.url = GURL(alternative_url);
16248 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016249 request3.traffic_annotation =
16250 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216251 TestCompletionCallback callback3;
16252
tfarina42834112016-09-22 13:38:2016253 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116254 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616255 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216256 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5216257 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4216258 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216259 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216260 EXPECT_FALSE(response3->was_fetched_via_spdy);
16261 std::string response_data3;
bnc691fda62016-08-12 00:43:1616262 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4216263 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
16264}
16265
bncd16676a2016-07-20 16:23:0116266TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2316267 const std::string https_url = "https://www.example.org:8080/";
16268 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0416269
rdsmithebb50aa2015-11-12 03:44:3816270 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0116271 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3816272
[email protected]8450d722012-07-02 19:14:0416273 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2316274 const HostPortPair host_port_pair("www.example.org", 8080);
Matt Menke6e879bd2019-03-18 17:26:0416275 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
16276 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
16277 host_port_pair));
Ryan Hamilton0239aac2018-05-19 00:03:1316278 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4916279 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1316280 spdy::SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0216281 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3916282
16283 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
Ryan Hamilton0239aac2018-05-19 00:03:1316284 spdy::SpdyHeaderBlock req2_block;
16285 req2_block[spdy::kHttp2MethodHeader] = "GET";
16286 req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
16287 req2_block[spdy::kHttp2SchemeHeader] = "http";
16288 req2_block[spdy::kHttp2PathHeader] = "/";
16289 spdy::SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1516290 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0416291
16292 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116293 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
16294 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0416295 };
16296
Ryan Hamilton0239aac2018-05-19 00:03:1316297 spdy::SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1516298 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316299 spdy::SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1516300 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316301 spdy::SpdySerializedFrame body1(
16302 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
16303 spdy::SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3816304 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316305 spdy::SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3816306 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
Raul Tambre94493c652019-03-11 17:18:3516307 spdy::SpdySerializedFrame resp2(
16308 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1316309 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3316310 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116311 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3316312 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4116313 CreateMockRead(wrapped_resp1, 4),
16314 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3316315 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4116316 CreateMockRead(resp2, 8),
16317 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3316318 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
16319 };
[email protected]8450d722012-07-02 19:14:0416320
Ryan Sleevib8d7ea02018-05-07 20:01:0116321 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0416322 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5716323 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0416324
Lily Houghton8c2f97d2018-01-22 05:06:5916325 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916326 ProxyResolutionService::CreateFixedFromPacResult(
16327 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5116328 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0716329 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0416330 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616331 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316332 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0416333 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616334 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316335 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16336 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0416337
danakj1fd259a02016-04-16 03:17:0916338 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0416339
16340 // Start the first transaction to set up the SpdySession
16341 HttpRequestInfo request1;
16342 request1.method = "GET";
16343 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0416344 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016345 request1.traffic_annotation =
16346 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016347 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0416348 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2016349 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416350
mmenke666a6fea2015-12-19 04:16:3316351 // This pause is a hack to avoid running into https://crbug.com/497228.
16352 data1.RunUntilPaused();
16353 base::RunLoop().RunUntilIdle();
16354 data1.Resume();
robpercival214763f2016-07-01 23:27:0116355 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0416356 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16357
[email protected]f6c63db52013-02-02 00:35:2216358 LoadTimingInfo load_timing_info1;
16359 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
16360 TestLoadTimingNotReusedWithPac(load_timing_info1,
16361 CONNECT_TIMING_HAS_SSL_TIMES);
16362
mmenke666a6fea2015-12-19 04:16:3316363 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0416364 HttpRequestInfo request2;
16365 request2.method = "GET";
16366 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0416367 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016368 request2.traffic_annotation =
16369 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016370 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0416371 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2016372 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416373
mmenke666a6fea2015-12-19 04:16:3316374 // This pause is a hack to avoid running into https://crbug.com/497228.
16375 data1.RunUntilPaused();
16376 base::RunLoop().RunUntilIdle();
16377 data1.Resume();
robpercival214763f2016-07-01 23:27:0116378 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3316379
[email protected]8450d722012-07-02 19:14:0416380 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2216381
16382 LoadTimingInfo load_timing_info2;
16383 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
16384 // The established SPDY sessions is considered reused by the HTTP request.
16385 TestLoadTimingReusedWithPac(load_timing_info2);
16386 // HTTP requests over a SPDY session should have a different connection
16387 // socket_log_id than requests over a tunnel.
16388 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0416389}
16390
[email protected]2d88e7d2012-07-19 17:55:1716391// Test that in the case where we have a SPDY session to a SPDY proxy
16392// that we do not pool other origins that resolve to the same IP when
16393// the certificate does not match the new origin.
16394// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0116395TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2316396 const std::string url1 = "http://www.example.org/";
16397 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1716398 const std::string ip_addr = "1.2.3.4";
16399
rdsmithebb50aa2015-11-12 03:44:3816400 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0116401 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3816402
[email protected]2d88e7d2012-07-19 17:55:1716403 // SPDY GET for HTTP URL (through SPDY proxy)
Ryan Hamilton0239aac2018-05-19 00:03:1316404 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2316405 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:1316406 spdy::SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1516407 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1716408
16409 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116410 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1716411 };
16412
Raul Tambre94493c652019-03-11 17:18:3516413 spdy::SpdySerializedFrame resp1(
16414 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316415 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1716416 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116417 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
16418 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1716419 };
16420
Ryan Sleevib8d7ea02018-05-07 20:01:0116421 SequencedSocketData data1(reads1, writes1);
martijnfe9636e2016-02-06 14:33:3216422 IPAddress ip;
martijn654c8c42016-02-10 22:10:5916423 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1716424 IPEndPoint peer_addr = IPEndPoint(ip, 443);
16425 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3316426 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1716427
16428 // SPDY GET for HTTPS URL (direct)
Ryan Hamilton0239aac2018-05-19 00:03:1316429 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916430 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1716431
16432 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116433 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1716434 };
16435
Ryan Hamilton0239aac2018-05-19 00:03:1316436 spdy::SpdySerializedFrame resp2(
Raul Tambre94493c652019-03-11 17:18:3516437 spdy_util_secure.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316438 spdy::SpdySerializedFrame body2(
16439 spdy_util_secure.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4116440 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3316441 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1716442
Ryan Sleevib8d7ea02018-05-07 20:01:0116443 SequencedSocketData data2(reads2, writes2);
[email protected]2d88e7d2012-07-19 17:55:1716444 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3316445 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1716446
16447 // Set up a proxy config that sends HTTP requests to a proxy, and
16448 // all others direct.
16449 ProxyConfig proxy_config;
16450 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4916451 session_deps_.proxy_resolution_service =
16452 std::make_unique<ProxyResolutionService>(
16453 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
16454 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
16455 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1716456
bncce36dca22015-04-21 22:11:2316457 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616458 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1716459 // Load a valid cert. Note, that this does not need to
16460 // be valid for proxy because the MockSSLClientSocket does
16461 // not actually verify it. But SpdySession will use this
16462 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4916463 ssl1.ssl_info.cert =
16464 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
16465 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3316466 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16467 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1716468
16469 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616470 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316471 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16472 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1716473
Jeremy Roman0579ed62017-08-29 15:56:1916474 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2316475 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0716476 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1716477
danakj1fd259a02016-04-16 03:17:0916478 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1716479
16480 // Start the first transaction to set up the SpdySession
16481 HttpRequestInfo request1;
16482 request1.method = "GET";
16483 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1716484 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016485 request1.traffic_annotation =
16486 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016487 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716488 TestCompletionCallback callback1;
16489 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016490 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3316491 // This pause is a hack to avoid running into https://crbug.com/497228.
16492 data1.RunUntilPaused();
16493 base::RunLoop().RunUntilIdle();
16494 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1716495
robpercival214763f2016-07-01 23:27:0116496 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716497 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16498
16499 // Now, start the HTTP request
16500 HttpRequestInfo request2;
16501 request2.method = "GET";
16502 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1716503 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016504 request2.traffic_annotation =
16505 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016506 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716507 TestCompletionCallback callback2;
16508 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016509 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516510 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1716511
16512 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0116513 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716514 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16515}
16516
[email protected]85f97342013-04-17 06:12:2416517// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
16518// error) in SPDY session, removes the socket from pool and closes the SPDY
16519// session. Verify that new url's from the same HttpNetworkSession (and a new
16520// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0116521TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2316522 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2416523
16524 MockRead reads1[] = {
16525 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
16526 };
16527
Ryan Sleevib8d7ea02018-05-07 20:01:0116528 SequencedSocketData data1(reads1, base::span<MockWrite>());
[email protected]85f97342013-04-17 06:12:2416529
Ryan Hamilton0239aac2018-05-19 00:03:1316530 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916531 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2416532 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116533 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2416534 };
16535
Raul Tambre94493c652019-03-11 17:18:3516536 spdy::SpdySerializedFrame resp2(
16537 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316538 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2416539 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4116540 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
16541 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2416542 };
16543
Ryan Sleevib8d7ea02018-05-07 20:01:0116544 SequencedSocketData data2(reads2, writes2);
[email protected]85f97342013-04-17 06:12:2416545
[email protected]85f97342013-04-17 06:12:2416546 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616547 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016548 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16549 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2416550
16551 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616552 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016553 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16554 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2416555
danakj1fd259a02016-04-16 03:17:0916556 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5016557 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2416558
16559 // Start the first transaction to set up the SpdySession and verify that
16560 // connection was closed.
16561 HttpRequestInfo request1;
16562 request1.method = "GET";
16563 request1.url = GURL(https_url);
16564 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016565 request1.traffic_annotation =
16566 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016567 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416568 TestCompletionCallback callback1;
16569 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016570 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116571 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2416572
16573 // Now, start the second request and make sure it succeeds.
16574 HttpRequestInfo request2;
16575 request2.method = "GET";
16576 request2.url = GURL(https_url);
16577 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016578 request2.traffic_annotation =
16579 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016580 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416581 TestCompletionCallback callback2;
16582 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016583 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2416584
robpercival214763f2016-07-01 23:27:0116585 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2416586 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16587}
16588
bncd16676a2016-07-20 16:23:0116589TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0316590 ClientSocketPoolManager::set_max_sockets_per_group(
16591 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16592 ClientSocketPoolManager::set_max_sockets_per_pool(
16593 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16594
16595 // Use two different hosts with different IPs so they don't get pooled.
16596 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
16597 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0916598 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0316599
16600 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616601 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316602 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616603 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316604 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16605 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16606
Ryan Hamilton0239aac2018-05-19 00:03:1316607 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4916608 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316609 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116610 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0316611 };
Ryan Hamilton0239aac2018-05-19 00:03:1316612 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3516613 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316614 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4116615 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316616 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116617 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916618 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316619 };
16620
rdsmithebb50aa2015-11-12 03:44:3816621 // Use a separate test instance for the separate SpdySession that will be
16622 // created.
bncd16676a2016-07-20 16:23:0116623 SpdyTestUtil spdy_util_2;
Ryan Sleevib8d7ea02018-05-07 20:01:0116624 SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
Bence Béky53a5aef2018-03-29 21:54:1216625 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0316626
Ryan Hamilton0239aac2018-05-19 00:03:1316627 spdy::SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4916628 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316629 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116630 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0316631 };
Ryan Hamilton0239aac2018-05-19 00:03:1316632 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3516633 spdy_util_2.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316634 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4116635 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316636 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116637 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916638 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316639 };
16640
Ryan Sleevib8d7ea02018-05-07 20:01:0116641 SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
Bence Béky53a5aef2018-03-29 21:54:1216642 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0316643
16644 MockWrite http_write[] = {
16645 MockWrite("GET / HTTP/1.1\r\n"
16646 "Host: www.a.com\r\n"
16647 "Connection: keep-alive\r\n\r\n"),
16648 };
16649
16650 MockRead http_read[] = {
16651 MockRead("HTTP/1.1 200 OK\r\n"),
16652 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16653 MockRead("Content-Length: 6\r\n\r\n"),
16654 MockRead("hello!"),
16655 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116656 StaticSocketDataProvider http_data(http_read, http_write);
[email protected]483fa202013-05-14 01:07:0316657 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16658
16659 HostPortPair host_port_pair_a("www.a.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116660 SpdySessionKey spdy_session_key_a(
16661 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16662 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316663 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616664 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316665
16666 TestCompletionCallback callback;
16667 HttpRequestInfo request1;
16668 request1.method = "GET";
16669 request1.url = GURL("https://www.a.com/");
16670 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016671 request1.traffic_annotation =
16672 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816673 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916674 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316675
tfarina42834112016-09-22 13:38:2016676 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116677 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16678 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316679
16680 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216681 ASSERT_TRUE(response);
16682 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216683 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316684 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216685 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0316686
16687 std::string response_data;
robpercival214763f2016-07-01 23:27:0116688 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316689 EXPECT_EQ("hello!", response_data);
16690 trans.reset();
16691 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616692 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316693
16694 HostPortPair host_port_pair_b("www.b.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116695 SpdySessionKey spdy_session_key_b(
16696 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16697 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316698 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616699 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316700 HttpRequestInfo request2;
16701 request2.method = "GET";
16702 request2.url = GURL("https://www.b.com/");
16703 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016704 request2.traffic_annotation =
16705 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816706 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916707 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316708
tfarina42834112016-09-22 13:38:2016709 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116710 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16711 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316712
16713 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216714 ASSERT_TRUE(response);
16715 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216716 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316717 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216718 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116719 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316720 EXPECT_EQ("hello!", response_data);
16721 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616722 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316723 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616724 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316725
16726 HostPortPair host_port_pair_a1("www.a.com", 80);
Matt Menke2436b2f2018-12-11 18:07:1116727 SpdySessionKey spdy_session_key_a1(
16728 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16729 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316730 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616731 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0316732 HttpRequestInfo request3;
16733 request3.method = "GET";
16734 request3.url = GURL("http://www.a.com/");
16735 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016736 request3.traffic_annotation =
16737 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816738 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916739 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316740
tfarina42834112016-09-22 13:38:2016741 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116742 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16743 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316744
16745 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216746 ASSERT_TRUE(response);
16747 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0316748 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16749 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216750 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116751 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316752 EXPECT_EQ("hello!", response_data);
16753 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616754 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316755 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616756 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316757}
16758
bncd16676a2016-07-20 16:23:0116759TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416760 HttpRequestInfo request;
16761 request.method = "GET";
bncce36dca22015-04-21 22:11:2316762 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016763 request.traffic_annotation =
16764 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416765
danakj1fd259a02016-04-16 03:17:0916766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616767 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416768
ttuttled9dbc652015-09-29 20:00:5916769 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416770 StaticSocketDataProvider data;
16771 data.set_connect_data(mock_connect);
16772 session_deps_.socket_factory->AddSocketDataProvider(&data);
16773
16774 TestCompletionCallback callback;
16775
tfarina42834112016-09-22 13:38:2016776 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116777 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416778
16779 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116780 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416781
[email protected]79e1fd62013-06-20 06:50:0416782 // We don't care whether this succeeds or fails, but it shouldn't crash.
16783 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616784 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716785
16786 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616787 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716788 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116789 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916790
16791 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616792 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916793 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416794}
16795
bncd16676a2016-07-20 16:23:0116796TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416797 HttpRequestInfo request;
16798 request.method = "GET";
bncce36dca22015-04-21 22:11:2316799 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016800 request.traffic_annotation =
16801 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416802
danakj1fd259a02016-04-16 03:17:0916803 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616804 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416805
ttuttled9dbc652015-09-29 20:00:5916806 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416807 StaticSocketDataProvider data;
16808 data.set_connect_data(mock_connect);
16809 session_deps_.socket_factory->AddSocketDataProvider(&data);
16810
16811 TestCompletionCallback callback;
16812
tfarina42834112016-09-22 13:38:2016813 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416815
16816 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116817 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416818
[email protected]79e1fd62013-06-20 06:50:0416819 // We don't care whether this succeeds or fails, but it shouldn't crash.
16820 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616821 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716822
16823 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616824 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716825 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116826 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916827
16828 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616829 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916830 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416831}
16832
bncd16676a2016-07-20 16:23:0116833TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416834 HttpRequestInfo request;
16835 request.method = "GET";
bncce36dca22015-04-21 22:11:2316836 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016837 request.traffic_annotation =
16838 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416839
danakj1fd259a02016-04-16 03:17:0916840 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616841 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416842
16843 MockWrite data_writes[] = {
16844 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16845 };
16846 MockRead data_reads[] = {
16847 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16848 };
16849
Ryan Sleevib8d7ea02018-05-07 20:01:0116850 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416851 session_deps_.socket_factory->AddSocketDataProvider(&data);
16852
16853 TestCompletionCallback callback;
16854
tfarina42834112016-09-22 13:38:2016855 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116856 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416857
16858 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116859 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416860
[email protected]79e1fd62013-06-20 06:50:0416861 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616862 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416863 EXPECT_TRUE(request_headers.HasHeader("Host"));
16864}
16865
bncd16676a2016-07-20 16:23:0116866TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416867 HttpRequestInfo request;
16868 request.method = "GET";
bncce36dca22015-04-21 22:11:2316869 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016870 request.traffic_annotation =
16871 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416872
danakj1fd259a02016-04-16 03:17:0916873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616874 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416875
16876 MockWrite data_writes[] = {
16877 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16878 };
16879 MockRead data_reads[] = {
16880 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16881 };
16882
Ryan Sleevib8d7ea02018-05-07 20:01:0116883 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416884 session_deps_.socket_factory->AddSocketDataProvider(&data);
16885
16886 TestCompletionCallback callback;
16887
tfarina42834112016-09-22 13:38:2016888 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116889 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416890
16891 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116892 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416893
[email protected]79e1fd62013-06-20 06:50:0416894 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616895 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416896 EXPECT_TRUE(request_headers.HasHeader("Host"));
16897}
16898
bncd16676a2016-07-20 16:23:0116899TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[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[] = {
bncce36dca22015-04-21 22:11:2316910 MockWrite(
16911 "GET / HTTP/1.1\r\n"
16912 "Host: www.example.org\r\n"
16913 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416914 };
16915 MockRead data_reads[] = {
16916 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16917 };
16918
Ryan Sleevib8d7ea02018-05-07 20:01:0116919 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416920 session_deps_.socket_factory->AddSocketDataProvider(&data);
16921
16922 TestCompletionCallback callback;
16923
tfarina42834112016-09-22 13:38:2016924 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416926
16927 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116928 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416929
[email protected]79e1fd62013-06-20 06:50:0416930 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616931 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416932 EXPECT_TRUE(request_headers.HasHeader("Host"));
16933}
16934
bncd16676a2016-07-20 16:23:0116935TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416936 HttpRequestInfo request;
16937 request.method = "GET";
bncce36dca22015-04-21 22:11:2316938 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016939 request.traffic_annotation =
16940 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416941
danakj1fd259a02016-04-16 03:17:0916942 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616943 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416944
16945 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316946 MockWrite(
16947 "GET / HTTP/1.1\r\n"
16948 "Host: www.example.org\r\n"
16949 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416950 };
16951 MockRead data_reads[] = {
16952 MockRead(ASYNC, ERR_CONNECTION_RESET),
16953 };
16954
Ryan Sleevib8d7ea02018-05-07 20:01:0116955 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416956 session_deps_.socket_factory->AddSocketDataProvider(&data);
16957
16958 TestCompletionCallback callback;
16959
tfarina42834112016-09-22 13:38:2016960 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116961 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416962
16963 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116964 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416965
[email protected]79e1fd62013-06-20 06:50:0416966 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616967 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416968 EXPECT_TRUE(request_headers.HasHeader("Host"));
16969}
16970
bncd16676a2016-07-20 16:23:0116971TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416972 HttpRequestInfo request;
16973 request.method = "GET";
bncce36dca22015-04-21 22:11:2316974 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416975 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:1016976 request.traffic_annotation =
16977 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416978
danakj1fd259a02016-04-16 03:17:0916979 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616980 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416981
16982 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316983 MockWrite(
16984 "GET / HTTP/1.1\r\n"
16985 "Host: www.example.org\r\n"
16986 "Connection: keep-alive\r\n"
16987 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416988 };
16989 MockRead data_reads[] = {
16990 MockRead("HTTP/1.1 200 OK\r\n"
16991 "Content-Length: 5\r\n\r\n"
16992 "hello"),
16993 MockRead(ASYNC, ERR_UNEXPECTED),
16994 };
16995
Ryan Sleevib8d7ea02018-05-07 20:01:0116996 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416997 session_deps_.socket_factory->AddSocketDataProvider(&data);
16998
16999 TestCompletionCallback callback;
17000
tfarina42834112016-09-22 13:38:2017001 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117002 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0417003
17004 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117005 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0417006
17007 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1617008 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0417009 std::string foo;
17010 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
17011 EXPECT_EQ("bar", foo);
17012}
17013
[email protected]043b68c82013-08-22 23:41:5217014// Tests that when a used socket is returned to the SSL socket pool, it's closed
17015// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117016TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5217017 ClientSocketPoolManager::set_max_sockets_per_group(
17018 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17019 ClientSocketPoolManager::set_max_sockets_per_pool(
17020 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17021
17022 // Set up SSL request.
17023
17024 HttpRequestInfo ssl_request;
17025 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2317026 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017027 ssl_request.traffic_annotation =
17028 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217029
17030 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2317031 MockWrite(
17032 "GET / HTTP/1.1\r\n"
17033 "Host: www.example.org\r\n"
17034 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217035 };
17036 MockRead ssl_reads[] = {
17037 MockRead("HTTP/1.1 200 OK\r\n"),
17038 MockRead("Content-Length: 11\r\n\r\n"),
17039 MockRead("hello world"),
17040 MockRead(SYNCHRONOUS, OK),
17041 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117042 StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
[email protected]043b68c82013-08-22 23:41:5217043 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17044
17045 SSLSocketDataProvider ssl(ASYNC, OK);
17046 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17047
17048 // Set up HTTP request.
17049
17050 HttpRequestInfo http_request;
17051 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317052 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017053 http_request.traffic_annotation =
17054 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217055
17056 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317057 MockWrite(
17058 "GET / HTTP/1.1\r\n"
17059 "Host: www.example.org\r\n"
17060 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217061 };
17062 MockRead http_reads[] = {
17063 MockRead("HTTP/1.1 200 OK\r\n"),
17064 MockRead("Content-Length: 7\r\n\r\n"),
17065 MockRead("falafel"),
17066 MockRead(SYNCHRONOUS, OK),
17067 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117068 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217069 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17070
danakj1fd259a02016-04-16 03:17:0917071 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217072
17073 // Start the SSL request.
17074 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1617075 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017076 ASSERT_EQ(ERR_IO_PENDING,
17077 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
17078 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5217079
17080 // Start the HTTP request. Pool should stall.
17081 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617082 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017083 ASSERT_EQ(ERR_IO_PENDING,
17084 http_trans.Start(&http_request, http_callback.callback(),
17085 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117086 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217087
17088 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0117089 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217090 std::string response_data;
bnc691fda62016-08-12 00:43:1617091 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217092 EXPECT_EQ("hello world", response_data);
17093
17094 // The SSL socket should automatically be closed, so the HTTP request can
17095 // start.
Matt Menke9d5e2c92019-02-05 01:42:2317096 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
dcheng48459ac22014-08-26 00:46:4117097 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217098
17099 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0117100 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1617101 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217102 EXPECT_EQ("falafel", response_data);
17103
dcheng48459ac22014-08-26 00:46:4117104 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217105}
17106
17107// Tests that when a SSL connection is established but there's no corresponding
17108// request that needs it, the new socket is closed if the transport socket pool
17109// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117110TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5217111 ClientSocketPoolManager::set_max_sockets_per_group(
17112 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17113 ClientSocketPoolManager::set_max_sockets_per_pool(
17114 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17115
17116 // Set up an ssl request.
17117
17118 HttpRequestInfo ssl_request;
17119 ssl_request.method = "GET";
17120 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1017121 ssl_request.traffic_annotation =
17122 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217123
17124 // No data will be sent on the SSL socket.
17125 StaticSocketDataProvider ssl_data;
17126 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17127
17128 SSLSocketDataProvider ssl(ASYNC, OK);
17129 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17130
17131 // Set up HTTP request.
17132
17133 HttpRequestInfo http_request;
17134 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317135 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017136 http_request.traffic_annotation =
17137 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217138
17139 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317140 MockWrite(
17141 "GET / HTTP/1.1\r\n"
17142 "Host: www.example.org\r\n"
17143 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217144 };
17145 MockRead http_reads[] = {
17146 MockRead("HTTP/1.1 200 OK\r\n"),
17147 MockRead("Content-Length: 7\r\n\r\n"),
17148 MockRead("falafel"),
17149 MockRead(SYNCHRONOUS, OK),
17150 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117151 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217152 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17153
danakj1fd259a02016-04-16 03:17:0917154 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217155
17156 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
17157 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2917158 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5917159 http_stream_factory->PreconnectStreams(1, ssl_request);
Matt Menke9d5e2c92019-02-05 01:42:2317160 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217161
17162 // Start the HTTP request. Pool should stall.
17163 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617164 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017165 ASSERT_EQ(ERR_IO_PENDING,
17166 http_trans.Start(&http_request, http_callback.callback(),
17167 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117168 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217169
17170 // The SSL connection will automatically be closed once the connection is
17171 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0117172 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217173 std::string response_data;
bnc691fda62016-08-12 00:43:1617174 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217175 EXPECT_EQ("falafel", response_data);
17176
dcheng48459ac22014-08-26 00:46:4117177 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217178}
17179
bncd16676a2016-07-20 16:23:0117180TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917181 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217182 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917183 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217184 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417185
17186 HttpRequestInfo request;
17187 request.method = "POST";
17188 request.url = GURL("http://www.foo.com/");
17189 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017190 request.traffic_annotation =
17191 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417192
danakj1fd259a02016-04-16 03:17:0917193 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617194 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417195 // Send headers successfully, but get an error while sending the body.
17196 MockWrite data_writes[] = {
17197 MockWrite("POST / HTTP/1.1\r\n"
17198 "Host: www.foo.com\r\n"
17199 "Connection: keep-alive\r\n"
17200 "Content-Length: 3\r\n\r\n"),
17201 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17202 };
17203
17204 MockRead data_reads[] = {
17205 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17206 MockRead("hello world"),
17207 MockRead(SYNCHRONOUS, OK),
17208 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117209 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417210 session_deps_.socket_factory->AddSocketDataProvider(&data);
17211
17212 TestCompletionCallback callback;
17213
tfarina42834112016-09-22 13:38:2017214 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117215 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417216
17217 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117218 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417219
bnc691fda62016-08-12 00:43:1617220 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217221 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417222
wezca1070932016-05-26 20:30:5217223 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417224 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17225
17226 std::string response_data;
bnc691fda62016-08-12 00:43:1617227 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117228 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417229 EXPECT_EQ("hello world", response_data);
17230}
17231
17232// This test makes sure the retry logic doesn't trigger when reading an error
17233// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0117234TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417235 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0917236 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5417237 MockWrite data_writes[] = {
17238 MockWrite("GET / HTTP/1.1\r\n"
17239 "Host: www.foo.com\r\n"
17240 "Connection: keep-alive\r\n\r\n"),
17241 MockWrite("POST / HTTP/1.1\r\n"
17242 "Host: www.foo.com\r\n"
17243 "Connection: keep-alive\r\n"
17244 "Content-Length: 3\r\n\r\n"),
17245 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17246 };
17247
17248 MockRead data_reads[] = {
17249 MockRead("HTTP/1.1 200 Peachy\r\n"
17250 "Content-Length: 14\r\n\r\n"),
17251 MockRead("first response"),
17252 MockRead("HTTP/1.1 400 Not OK\r\n"
17253 "Content-Length: 15\r\n\r\n"),
17254 MockRead("second response"),
17255 MockRead(SYNCHRONOUS, OK),
17256 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117257 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417258 session_deps_.socket_factory->AddSocketDataProvider(&data);
17259
17260 TestCompletionCallback callback;
17261 HttpRequestInfo request1;
17262 request1.method = "GET";
17263 request1.url = GURL("http://www.foo.com/");
17264 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1017265 request1.traffic_annotation =
17266 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417267
bnc87dcefc2017-05-25 12:47:5817268 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1917269 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017270 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117271 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417272
17273 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117274 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417275
17276 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5217277 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5417278
wezca1070932016-05-26 20:30:5217279 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5417280 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
17281
17282 std::string response_data1;
17283 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0117284 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417285 EXPECT_EQ("first response", response_data1);
17286 // Delete the transaction to release the socket back into the socket pool.
17287 trans1.reset();
17288
danakj1fd259a02016-04-16 03:17:0917289 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217290 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917291 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217292 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417293
17294 HttpRequestInfo request2;
17295 request2.method = "POST";
17296 request2.url = GURL("http://www.foo.com/");
17297 request2.upload_data_stream = &upload_data_stream;
17298 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1017299 request2.traffic_annotation =
17300 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417301
bnc691fda62016-08-12 00:43:1617302 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017303 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417305
17306 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117307 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417308
bnc691fda62016-08-12 00:43:1617309 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5217310 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5417311
wezca1070932016-05-26 20:30:5217312 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5417313 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
17314
17315 std::string response_data2;
bnc691fda62016-08-12 00:43:1617316 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0117317 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417318 EXPECT_EQ("second response", response_data2);
17319}
17320
bncd16676a2016-07-20 16:23:0117321TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417322 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0917323 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217324 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917325 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217326 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417327
17328 HttpRequestInfo request;
17329 request.method = "POST";
17330 request.url = GURL("http://www.foo.com/");
17331 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017332 request.traffic_annotation =
17333 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417334
danakj1fd259a02016-04-16 03:17:0917335 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617336 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417337 // Send headers successfully, but get an error while sending the body.
17338 MockWrite data_writes[] = {
17339 MockWrite("POST / HTTP/1.1\r\n"
17340 "Host: www.foo.com\r\n"
17341 "Connection: keep-alive\r\n"
17342 "Content-Length: 3\r\n\r\n"
17343 "fo"),
17344 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17345 };
17346
17347 MockRead data_reads[] = {
17348 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17349 MockRead("hello world"),
17350 MockRead(SYNCHRONOUS, OK),
17351 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117352 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417353 session_deps_.socket_factory->AddSocketDataProvider(&data);
17354
17355 TestCompletionCallback callback;
17356
tfarina42834112016-09-22 13:38:2017357 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117358 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417359
17360 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117361 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417362
bnc691fda62016-08-12 00:43:1617363 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217364 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417365
wezca1070932016-05-26 20:30:5217366 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417367 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17368
17369 std::string response_data;
bnc691fda62016-08-12 00:43:1617370 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117371 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417372 EXPECT_EQ("hello world", response_data);
17373}
17374
17375// This tests the more common case than the previous test, where headers and
17376// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0117377TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0717378 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5417379
17380 HttpRequestInfo request;
17381 request.method = "POST";
17382 request.url = GURL("http://www.foo.com/");
17383 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017384 request.traffic_annotation =
17385 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417386
danakj1fd259a02016-04-16 03:17:0917387 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617388 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417389 // Send headers successfully, but get an error while sending the body.
17390 MockWrite data_writes[] = {
17391 MockWrite("POST / HTTP/1.1\r\n"
17392 "Host: www.foo.com\r\n"
17393 "Connection: keep-alive\r\n"
17394 "Transfer-Encoding: chunked\r\n\r\n"),
17395 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17396 };
17397
17398 MockRead data_reads[] = {
17399 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17400 MockRead("hello world"),
17401 MockRead(SYNCHRONOUS, OK),
17402 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117403 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417404 session_deps_.socket_factory->AddSocketDataProvider(&data);
17405
17406 TestCompletionCallback callback;
17407
tfarina42834112016-09-22 13:38:2017408 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417410 // Make sure the headers are sent before adding a chunk. This ensures that
17411 // they can't be merged with the body in a single send. Not currently
17412 // necessary since a chunked body is never merged with headers, but this makes
17413 // the test more future proof.
17414 base::RunLoop().RunUntilIdle();
17415
mmenkecbc2b712014-10-09 20:29:0717416 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5417417
17418 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117419 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417420
bnc691fda62016-08-12 00:43:1617421 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217422 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417423
wezca1070932016-05-26 20:30:5217424 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417425 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17426
17427 std::string response_data;
bnc691fda62016-08-12 00:43:1617428 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117429 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417430 EXPECT_EQ("hello world", response_data);
17431}
17432
bncd16676a2016-07-20 16:23:0117433TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917434 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217435 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917436 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217437 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417438
17439 HttpRequestInfo request;
17440 request.method = "POST";
17441 request.url = GURL("http://www.foo.com/");
17442 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017443 request.traffic_annotation =
17444 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417445
danakj1fd259a02016-04-16 03:17:0917446 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617447 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417448
17449 MockWrite data_writes[] = {
17450 MockWrite("POST / HTTP/1.1\r\n"
17451 "Host: www.foo.com\r\n"
17452 "Connection: keep-alive\r\n"
17453 "Content-Length: 3\r\n\r\n"),
17454 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17455 };
17456
17457 MockRead data_reads[] = {
17458 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17459 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17460 MockRead("hello world"),
17461 MockRead(SYNCHRONOUS, OK),
17462 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117463 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417464 session_deps_.socket_factory->AddSocketDataProvider(&data);
17465
17466 TestCompletionCallback callback;
17467
tfarina42834112016-09-22 13:38:2017468 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117469 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417470
17471 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117472 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417473
bnc691fda62016-08-12 00:43:1617474 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217475 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417476
wezca1070932016-05-26 20:30:5217477 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417478 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17479
17480 std::string response_data;
bnc691fda62016-08-12 00:43:1617481 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117482 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417483 EXPECT_EQ("hello world", response_data);
17484}
17485
bncd16676a2016-07-20 16:23:0117486TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917487 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217488 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917489 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217490 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417491
17492 HttpRequestInfo request;
17493 request.method = "POST";
17494 request.url = GURL("http://www.foo.com/");
17495 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017496 request.traffic_annotation =
17497 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417498
danakj1fd259a02016-04-16 03:17:0917499 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617500 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417501 // Send headers successfully, but get an error while sending the body.
17502 MockWrite data_writes[] = {
17503 MockWrite("POST / HTTP/1.1\r\n"
17504 "Host: www.foo.com\r\n"
17505 "Connection: keep-alive\r\n"
17506 "Content-Length: 3\r\n\r\n"),
17507 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17508 };
17509
17510 MockRead data_reads[] = {
17511 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17512 MockRead("hello world"),
17513 MockRead(SYNCHRONOUS, OK),
17514 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117515 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417516 session_deps_.socket_factory->AddSocketDataProvider(&data);
17517
17518 TestCompletionCallback callback;
17519
tfarina42834112016-09-22 13:38:2017520 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117521 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417522
17523 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117524 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417525}
17526
bncd16676a2016-07-20 16:23:0117527TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417528 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917529 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217530 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917531 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217532 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417533
17534 HttpRequestInfo request;
17535 request.method = "POST";
17536 request.url = GURL("http://www.foo.com/");
17537 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017538 request.traffic_annotation =
17539 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417540
danakj1fd259a02016-04-16 03:17:0917541 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617542 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417543 // Send headers successfully, but get an error while sending the body.
17544 MockWrite data_writes[] = {
17545 MockWrite("POST / HTTP/1.1\r\n"
17546 "Host: www.foo.com\r\n"
17547 "Connection: keep-alive\r\n"
17548 "Content-Length: 3\r\n\r\n"),
17549 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17550 };
17551
17552 MockRead data_reads[] = {
17553 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17554 MockRead("HTTP/1.0 302 Redirect\r\n"),
17555 MockRead("Location: http://somewhere-else.com/\r\n"),
17556 MockRead("Content-Length: 0\r\n\r\n"),
17557 MockRead(SYNCHRONOUS, OK),
17558 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117559 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417560 session_deps_.socket_factory->AddSocketDataProvider(&data);
17561
17562 TestCompletionCallback callback;
17563
tfarina42834112016-09-22 13:38:2017564 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117565 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417566
17567 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117568 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417569}
17570
bncd16676a2016-07-20 16:23:0117571TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917572 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217573 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917574 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217575 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417576
17577 HttpRequestInfo request;
17578 request.method = "POST";
17579 request.url = GURL("http://www.foo.com/");
17580 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017581 request.traffic_annotation =
17582 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417583
danakj1fd259a02016-04-16 03:17:0917584 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617585 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417586 // Send headers successfully, but get an error while sending the body.
17587 MockWrite data_writes[] = {
17588 MockWrite("POST / HTTP/1.1\r\n"
17589 "Host: www.foo.com\r\n"
17590 "Connection: keep-alive\r\n"
17591 "Content-Length: 3\r\n\r\n"),
17592 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17593 };
17594
17595 MockRead data_reads[] = {
17596 MockRead("HTTP 0.9 rocks!"),
17597 MockRead(SYNCHRONOUS, OK),
17598 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117599 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417600 session_deps_.socket_factory->AddSocketDataProvider(&data);
17601
17602 TestCompletionCallback callback;
17603
tfarina42834112016-09-22 13:38:2017604 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417606
17607 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117608 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417609}
17610
bncd16676a2016-07-20 16:23:0117611TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917612 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217613 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917614 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217615 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417616
17617 HttpRequestInfo request;
17618 request.method = "POST";
17619 request.url = GURL("http://www.foo.com/");
17620 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017621 request.traffic_annotation =
17622 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417623
danakj1fd259a02016-04-16 03:17:0917624 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617625 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417626 // Send headers successfully, but get an error while sending the body.
17627 MockWrite data_writes[] = {
17628 MockWrite("POST / HTTP/1.1\r\n"
17629 "Host: www.foo.com\r\n"
17630 "Connection: keep-alive\r\n"
17631 "Content-Length: 3\r\n\r\n"),
17632 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17633 };
17634
17635 MockRead data_reads[] = {
17636 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17637 MockRead(SYNCHRONOUS, OK),
17638 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117639 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417640 session_deps_.socket_factory->AddSocketDataProvider(&data);
17641
17642 TestCompletionCallback callback;
17643
tfarina42834112016-09-22 13:38:2017644 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117645 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417646
17647 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117648 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417649}
17650
Bence Békydca6bd92018-01-30 13:43:0617651#if BUILDFLAG(ENABLE_WEBSOCKETS)
17652
17653namespace {
17654
17655void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17656 headers->SetHeader("Connection", "Upgrade");
17657 headers->SetHeader("Upgrade", "websocket");
17658 headers->SetHeader("Origin", "http://www.example.org");
17659 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617660}
17661
17662} // namespace
17663
17664TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Béky2fcf4fa2018-04-06 20:06:0117665 for (bool secure : {true, false}) {
17666 MockWrite data_writes[] = {
17667 MockWrite("GET / HTTP/1.1\r\n"
17668 "Host: www.example.org\r\n"
17669 "Connection: Upgrade\r\n"
17670 "Upgrade: websocket\r\n"
17671 "Origin: http://www.example.org\r\n"
17672 "Sec-WebSocket-Version: 13\r\n"
17673 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17674 "Sec-WebSocket-Extensions: permessage-deflate; "
17675 "client_max_window_bits\r\n\r\n")};
17676
17677 MockRead data_reads[] = {
17678 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17679 "Upgrade: websocket\r\n"
17680 "Connection: Upgrade\r\n"
17681 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
17682
Ryan Sleevib8d7ea02018-05-07 20:01:0117683 StaticSocketDataProvider data(data_reads, data_writes);
Bence Béky2fcf4fa2018-04-06 20:06:0117684 session_deps_.socket_factory->AddSocketDataProvider(&data);
17685 SSLSocketDataProvider ssl(ASYNC, OK);
17686 if (secure)
17687 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
Bence Békydca6bd92018-01-30 13:43:0617688
17689 HttpRequestInfo request;
17690 request.method = "GET";
Bence Béky2fcf4fa2018-04-06 20:06:0117691 request.url =
17692 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17693 AddWebSocketHeaders(&request.extra_headers);
Ramin Halavatib5e433e62018-02-07 07:41:1017694 request.traffic_annotation =
17695 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617696
Bence Béky2fcf4fa2018-04-06 20:06:0117697 TestWebSocketHandshakeStreamCreateHelper
17698 websocket_handshake_stream_create_helper;
Bence Béky8d1c6052018-02-07 12:48:1517699
Bence Béky2fcf4fa2018-04-06 20:06:0117700 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Bence Békydca6bd92018-01-30 13:43:0617701 HttpNetworkTransaction trans(LOW, session.get());
17702 trans.SetWebSocketHandshakeStreamCreateHelper(
Bence Béky2fcf4fa2018-04-06 20:06:0117703 &websocket_handshake_stream_create_helper);
Bence Békydca6bd92018-01-30 13:43:0617704
17705 TestCompletionCallback callback;
Bence Béky2fcf4fa2018-04-06 20:06:0117706 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17707 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Bence Békydca6bd92018-01-30 13:43:0617708
Bence Béky2fcf4fa2018-04-06 20:06:0117709 const HttpStreamRequest* stream_request = trans.stream_request_.get();
17710 ASSERT_TRUE(stream_request);
17711 EXPECT_EQ(&websocket_handshake_stream_create_helper,
17712 stream_request->websocket_handshake_stream_create_helper());
17713
17714 rv = callback.WaitForResult();
17715 EXPECT_THAT(rv, IsOk());
17716
17717 EXPECT_TRUE(data.AllReadDataConsumed());
17718 EXPECT_TRUE(data.AllWriteDataConsumed());
Bence Békydca6bd92018-01-30 13:43:0617719 }
17720}
17721
Adam Rice425cf122015-01-19 06:18:2417722// Verify that proxy headers are not sent to the destination server when
17723// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117724TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417725 HttpRequestInfo request;
17726 request.method = "GET";
bncce36dca22015-04-21 22:11:2317727 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017728 request.traffic_annotation =
17729 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417730 AddWebSocketHeaders(&request.extra_headers);
17731
17732 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917733 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917734 ProxyResolutionService::CreateFixedFromPacResult(
17735 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417736
danakj1fd259a02016-04-16 03:17:0917737 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417738
17739 // Since a proxy is configured, try to establish a tunnel.
17740 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717741 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17742 "Host: www.example.org:443\r\n"
17743 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417744
17745 // After calling trans->RestartWithAuth(), this is the request we should
17746 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717747 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17748 "Host: www.example.org:443\r\n"
17749 "Proxy-Connection: keep-alive\r\n"
17750 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417751
rsleevidb16bb02015-11-12 23:47:1717752 MockWrite("GET / HTTP/1.1\r\n"
17753 "Host: www.example.org\r\n"
17754 "Connection: Upgrade\r\n"
17755 "Upgrade: websocket\r\n"
17756 "Origin: http://www.example.org\r\n"
17757 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517758 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17759 "Sec-WebSocket-Extensions: permessage-deflate; "
17760 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417761
17762 // The proxy responds to the connect with a 407, using a persistent
17763 // connection.
17764 MockRead data_reads[] = {
17765 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517766 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17767 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17768 "Content-Length: 0\r\n"
17769 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417770
17771 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17772
Bence Béky8d1c6052018-02-07 12:48:1517773 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17774 "Upgrade: websocket\r\n"
17775 "Connection: Upgrade\r\n"
17776 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417777
Ryan Sleevib8d7ea02018-05-07 20:01:0117778 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417779 session_deps_.socket_factory->AddSocketDataProvider(&data);
17780 SSLSocketDataProvider ssl(ASYNC, OK);
17781 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17782
Bence Béky8d1c6052018-02-07 12:48:1517783 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17784
bnc87dcefc2017-05-25 12:47:5817785 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917786 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417787 trans->SetWebSocketHandshakeStreamCreateHelper(
17788 &websocket_stream_create_helper);
17789
17790 {
17791 TestCompletionCallback callback;
17792
tfarina42834112016-09-22 13:38:2017793 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117794 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417795
17796 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117797 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417798 }
17799
17800 const HttpResponseInfo* response = trans->GetResponseInfo();
17801 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217802 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417803 EXPECT_EQ(407, response->headers->response_code());
17804
17805 {
17806 TestCompletionCallback callback;
17807
17808 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17809 callback.callback());
robpercival214763f2016-07-01 23:27:0117810 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417811
17812 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117813 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417814 }
17815
17816 response = trans->GetResponseInfo();
17817 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217818 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417819
17820 EXPECT_EQ(101, response->headers->response_code());
17821
17822 trans.reset();
17823 session->CloseAllConnections();
17824}
17825
17826// Verify that proxy headers are not sent to the destination server when
17827// establishing a tunnel for an insecure WebSocket connection.
17828// This requires the authentication info to be injected into the auth cache
17829// due to crbug.com/395064
17830// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117831TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417832 HttpRequestInfo request;
17833 request.method = "GET";
bncce36dca22015-04-21 22:11:2317834 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017835 request.traffic_annotation =
17836 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417837 AddWebSocketHeaders(&request.extra_headers);
17838
17839 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917840 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917841 ProxyResolutionService::CreateFixedFromPacResult(
17842 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417843
danakj1fd259a02016-04-16 03:17:0917844 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417845
17846 MockWrite data_writes[] = {
17847 // Try to establish a tunnel for the WebSocket connection, with
17848 // credentials. Because WebSockets have a separate set of socket pools,
17849 // they cannot and will not use the same TCP/IP connection as the
17850 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517851 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17852 "Host: www.example.org:80\r\n"
17853 "Proxy-Connection: keep-alive\r\n"
17854 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417855
Bence Béky8d1c6052018-02-07 12:48:1517856 MockWrite("GET / HTTP/1.1\r\n"
17857 "Host: www.example.org\r\n"
17858 "Connection: Upgrade\r\n"
17859 "Upgrade: websocket\r\n"
17860 "Origin: http://www.example.org\r\n"
17861 "Sec-WebSocket-Version: 13\r\n"
17862 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17863 "Sec-WebSocket-Extensions: permessage-deflate; "
17864 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417865
17866 MockRead data_reads[] = {
17867 // HTTP CONNECT with credentials.
17868 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17869
17870 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517871 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17872 "Upgrade: websocket\r\n"
17873 "Connection: Upgrade\r\n"
17874 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417875
Ryan Sleevib8d7ea02018-05-07 20:01:0117876 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417877 session_deps_.socket_factory->AddSocketDataProvider(&data);
17878
17879 session->http_auth_cache()->Add(
17880 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17881 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17882
Bence Béky8d1c6052018-02-07 12:48:1517883 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17884
bnc87dcefc2017-05-25 12:47:5817885 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917886 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417887 trans->SetWebSocketHandshakeStreamCreateHelper(
17888 &websocket_stream_create_helper);
17889
17890 TestCompletionCallback callback;
17891
tfarina42834112016-09-22 13:38:2017892 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417894
17895 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117896 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417897
17898 const HttpResponseInfo* response = trans->GetResponseInfo();
17899 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217900 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417901
17902 EXPECT_EQ(101, response->headers->response_code());
17903
17904 trans.reset();
17905 session->CloseAllConnections();
17906}
17907
Matt Menke1d6093e32019-03-22 17:33:4317908// WebSockets over QUIC is not supported, including over QUIC proxies.
17909TEST_F(HttpNetworkTransactionTest, WebSocketNotSentOverQuicProxy) {
17910 for (bool secure : {true, false}) {
17911 SCOPED_TRACE(secure);
17912 session_deps_.proxy_resolution_service =
17913 ProxyResolutionService::CreateFixedFromPacResult(
17914 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
17915 session_deps_.enable_quic = true;
17916
17917 HttpRequestInfo request;
17918 request.url =
17919 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17920 AddWebSocketHeaders(&request.extra_headers);
17921 request.traffic_annotation =
17922 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17923
17924 TestWebSocketHandshakeStreamCreateHelper
17925 websocket_handshake_stream_create_helper;
17926
17927 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17928 HttpNetworkTransaction trans(LOW, session.get());
17929 trans.SetWebSocketHandshakeStreamCreateHelper(
17930 &websocket_handshake_stream_create_helper);
17931
17932 TestCompletionCallback callback;
17933 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17934 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17935
17936 rv = callback.WaitForResult();
17937 EXPECT_THAT(rv, IsError(ERR_NO_SUPPORTED_PROXIES));
17938 }
17939}
17940
Bence Békydca6bd92018-01-30 13:43:0617941#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17942
bncd16676a2016-07-20 16:23:0117943TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917944 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217945 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917946 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217947 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217948
17949 HttpRequestInfo request;
17950 request.method = "POST";
17951 request.url = GURL("http://www.foo.com/");
17952 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017953 request.traffic_annotation =
17954 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217955
danakj1fd259a02016-04-16 03:17:0917956 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617957 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217958 MockWrite data_writes[] = {
17959 MockWrite("POST / HTTP/1.1\r\n"
17960 "Host: www.foo.com\r\n"
17961 "Connection: keep-alive\r\n"
17962 "Content-Length: 3\r\n\r\n"),
17963 MockWrite("foo"),
17964 };
17965
17966 MockRead data_reads[] = {
17967 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17968 MockRead(SYNCHRONOUS, OK),
17969 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117970 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217971 session_deps_.socket_factory->AddSocketDataProvider(&data);
17972
17973 TestCompletionCallback callback;
17974
17975 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017976 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117977 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217978
17979 std::string response_data;
bnc691fda62016-08-12 00:43:1617980 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217981
Ryan Sleevib8d7ea02018-05-07 20:01:0117982 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17983 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217984}
17985
bncd16676a2016-07-20 16:23:0117986TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917987 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217988 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917989 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217990 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217991
17992 HttpRequestInfo request;
17993 request.method = "POST";
17994 request.url = GURL("http://www.foo.com/");
17995 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017996 request.traffic_annotation =
17997 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217998
danakj1fd259a02016-04-16 03:17:0917999 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618000 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218001 MockWrite data_writes[] = {
18002 MockWrite("POST / HTTP/1.1\r\n"
18003 "Host: www.foo.com\r\n"
18004 "Connection: keep-alive\r\n"
18005 "Content-Length: 3\r\n\r\n"),
18006 MockWrite("foo"),
18007 };
18008
18009 MockRead data_reads[] = {
18010 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
18011 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18012 MockRead(SYNCHRONOUS, OK),
18013 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118014 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218015 session_deps_.socket_factory->AddSocketDataProvider(&data);
18016
18017 TestCompletionCallback callback;
18018
18019 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018020 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0118021 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218022
18023 std::string response_data;
bnc691fda62016-08-12 00:43:1618024 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218025
Ryan Sleevib8d7ea02018-05-07 20:01:0118026 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18027 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218028}
18029
bncd16676a2016-07-20 16:23:0118030TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2218031 ChunkedUploadDataStream upload_data_stream(0);
18032
18033 HttpRequestInfo request;
18034 request.method = "POST";
18035 request.url = GURL("http://www.foo.com/");
18036 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1018037 request.traffic_annotation =
18038 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218039
danakj1fd259a02016-04-16 03:17:0918040 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618041 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218042 // Send headers successfully, but get an error while sending the body.
18043 MockWrite data_writes[] = {
18044 MockWrite("POST / HTTP/1.1\r\n"
18045 "Host: www.foo.com\r\n"
18046 "Connection: keep-alive\r\n"
18047 "Transfer-Encoding: chunked\r\n\r\n"),
18048 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
18049 };
18050
18051 MockRead data_reads[] = {
18052 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18053 MockRead(SYNCHRONOUS, OK),
18054 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118055 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218056 session_deps_.socket_factory->AddSocketDataProvider(&data);
18057
18058 TestCompletionCallback callback;
18059
18060 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018061 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2218062
18063 base::RunLoop().RunUntilIdle();
18064 upload_data_stream.AppendData("f", 1, false);
18065
18066 base::RunLoop().RunUntilIdle();
18067 upload_data_stream.AppendData("oo", 2, true);
18068
robpercival214763f2016-07-01 23:27:0118069 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218070
18071 std::string response_data;
bnc691fda62016-08-12 00:43:1618072 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218073
Ryan Sleevib8d7ea02018-05-07 20:01:0118074 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18075 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218076}
18077
eustasc7d27da2017-04-06 10:33:2018078void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
18079 const std::string& accept_encoding,
18080 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0318081 const std::string& location,
eustasc7d27da2017-04-06 10:33:2018082 bool should_match) {
18083 HttpRequestInfo request;
18084 request.method = "GET";
18085 request.url = GURL("http://www.foo.com/");
18086 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
18087 accept_encoding);
Ramin Halavatib5e433e62018-02-07 07:41:1018088 request.traffic_annotation =
18089 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2018090
18091 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
18092 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18093 // Send headers successfully, but get an error while sending the body.
18094 MockWrite data_writes[] = {
18095 MockWrite("GET / HTTP/1.1\r\n"
18096 "Host: www.foo.com\r\n"
18097 "Connection: keep-alive\r\n"
18098 "Accept-Encoding: "),
18099 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
18100 };
18101
sky50576f32017-05-01 19:28:0318102 std::string response_code = "200 OK";
18103 std::string extra;
18104 if (!location.empty()) {
18105 response_code = "301 Redirect\r\nLocation: ";
18106 response_code.append(location);
18107 }
18108
eustasc7d27da2017-04-06 10:33:2018109 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0318110 MockRead("HTTP/1.0 "),
18111 MockRead(response_code.data()),
18112 MockRead("\r\nContent-Encoding: "),
18113 MockRead(content_encoding.data()),
18114 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2018115 MockRead(SYNCHRONOUS, OK),
18116 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118117 StaticSocketDataProvider data(data_reads, data_writes);
eustasc7d27da2017-04-06 10:33:2018118 session_deps->socket_factory->AddSocketDataProvider(&data);
18119
18120 TestCompletionCallback callback;
18121
18122 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18123 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18124
18125 rv = callback.WaitForResult();
18126 if (should_match) {
18127 EXPECT_THAT(rv, IsOk());
18128 } else {
18129 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
18130 }
18131}
18132
18133TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0318134 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2018135}
18136
18137TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0318138 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
18139 true);
eustasc7d27da2017-04-06 10:33:2018140}
18141
18142TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
18143 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0318144 "", false);
18145}
18146
18147TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
18148 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
18149 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2018150}
18151
xunjieli96f2a402017-06-05 17:24:2718152TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
18153 ProxyConfig proxy_config;
18154 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18155 proxy_config.set_pac_mandatory(true);
18156 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918157 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918158 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18159 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0418160 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2718161
18162 HttpRequestInfo request;
18163 request.method = "GET";
18164 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018165 request.traffic_annotation =
18166 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718167
18168 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18169 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18170
18171 TestCompletionCallback callback;
18172
18173 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18174 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18175 EXPECT_THAT(callback.WaitForResult(),
18176 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18177}
18178
18179TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
18180 ProxyConfig proxy_config;
18181 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18182 proxy_config.set_pac_mandatory(true);
18183 MockAsyncProxyResolverFactory* proxy_resolver_factory =
18184 new MockAsyncProxyResolverFactory(false);
18185 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918186 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918187 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18188 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5918189 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2718190 HttpRequestInfo request;
18191 request.method = "GET";
18192 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018193 request.traffic_annotation =
18194 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718195
18196 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18197 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18198
18199 TestCompletionCallback callback;
18200 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18201 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18202
18203 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
18204 ERR_FAILED, &resolver);
18205 EXPECT_THAT(callback.WaitForResult(),
18206 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18207}
18208
18209TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5918210 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4918211 ProxyResolutionService::CreateFixedFromPacResult(
18212 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718213 session_deps_.enable_quic = false;
18214 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18215
18216 HttpRequestInfo request;
18217 request.method = "GET";
18218 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018219 request.traffic_annotation =
18220 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718221
18222 TestCompletionCallback callback;
18223 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18224 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18225 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18226
18227 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18228}
18229
Douglas Creager3cb042052018-11-06 23:08:5218230//-----------------------------------------------------------------------------
Douglas Creager134b52e2018-11-09 18:00:1418231// Reporting tests
18232
18233#if BUILDFLAG(ENABLE_REPORTING)
18234class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest {
18235 protected:
18236 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618237 HttpNetworkTransactionTest::SetUp();
Douglas Creager134b52e2018-11-09 18:00:1418238 auto test_reporting_context = std::make_unique<TestReportingContext>(
18239 &clock_, &tick_clock_, ReportingPolicy());
18240 test_reporting_context_ = test_reporting_context.get();
18241 session_deps_.reporting_service =
18242 ReportingService::CreateForTesting(std::move(test_reporting_context));
18243 }
18244
18245 TestReportingContext* reporting_context() const {
18246 return test_reporting_context_;
18247 }
18248
18249 void clear_reporting_service() {
18250 session_deps_.reporting_service.reset();
18251 test_reporting_context_ = nullptr;
18252 }
18253
18254 // Makes an HTTPS request that should install a valid Reporting policy.
Lily Chenfec60d92019-01-24 01:16:4218255 void RequestPolicy(CertStatus cert_status = 0) {
18256 HttpRequestInfo request;
18257 request.method = "GET";
18258 request.url = GURL(url_);
18259 request.traffic_annotation =
18260 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18261
Lily Chend3930e72019-03-01 19:31:1118262 MockWrite data_writes[] = {
18263 MockWrite("GET / HTTP/1.1\r\n"
18264 "Host: www.example.org\r\n"
18265 "Connection: keep-alive\r\n\r\n"),
18266 };
Douglas Creager134b52e2018-11-09 18:00:1418267 MockRead data_reads[] = {
18268 MockRead("HTTP/1.0 200 OK\r\n"),
18269 MockRead("Report-To: {\"group\": \"nel\", \"max_age\": 86400, "
18270 "\"endpoints\": [{\"url\": "
18271 "\"https://www.example.org/upload/\"}]}\r\n"),
18272 MockRead("\r\n"),
18273 MockRead("hello world"),
18274 MockRead(SYNCHRONOUS, OK),
18275 };
Douglas Creager134b52e2018-11-09 18:00:1418276
Lily Chenfec60d92019-01-24 01:16:4218277 StaticSocketDataProvider reads(data_reads, data_writes);
18278 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager134b52e2018-11-09 18:00:1418279
18280 SSLSocketDataProvider ssl(ASYNC, OK);
18281 if (request.url.SchemeIsCryptographic()) {
18282 ssl.ssl_info.cert =
18283 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18284 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218285 ssl.ssl_info.cert_status = cert_status;
Douglas Creager134b52e2018-11-09 18:00:1418286 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18287 }
18288
Douglas Creager134b52e2018-11-09 18:00:1418289 TestCompletionCallback callback;
18290 auto session = CreateSession(&session_deps_);
18291 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18292 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
Lily Chenfec60d92019-01-24 01:16:4218293 EXPECT_THAT(callback.GetResult(rv), IsOk());
Douglas Creager134b52e2018-11-09 18:00:1418294 }
18295
18296 protected:
18297 std::string url_ = "https://www.example.org/";
Douglas Creager134b52e2018-11-09 18:00:1418298
18299 private:
18300 TestReportingContext* test_reporting_context_;
18301};
18302
18303TEST_F(HttpNetworkTransactionReportingTest,
18304 DontProcessReportToHeaderNoService) {
18305 base::HistogramTester histograms;
18306 clear_reporting_service();
18307 RequestPolicy();
18308 histograms.ExpectBucketCount(
18309 ReportingHeaderParser::kHeaderOutcomeHistogram,
18310 ReportingHeaderParser::HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE, 1);
18311}
18312
18313TEST_F(HttpNetworkTransactionReportingTest, DontProcessReportToHeaderHttp) {
18314 base::HistogramTester histograms;
18315 url_ = "http://www.example.org/";
18316 RequestPolicy();
18317 histograms.ExpectBucketCount(
18318 ReportingHeaderParser::kHeaderOutcomeHistogram,
18319 ReportingHeaderParser::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18320}
18321
18322TEST_F(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
18323 RequestPolicy();
Lily Chenefb6fcf2019-04-19 04:17:5418324 ASSERT_EQ(1u, reporting_context()->cache()->GetEndpointCount());
18325 const ReportingClient endpoint =
18326 reporting_context()->cache()->GetEndpointForTesting(
18327 url::Origin::Create(GURL("https://www.example.org/")), "nel",
18328 GURL("https://www.example.org/upload/"));
18329 EXPECT_TRUE(endpoint);
Douglas Creager134b52e2018-11-09 18:00:1418330}
18331
18332TEST_F(HttpNetworkTransactionReportingTest,
18333 DontProcessReportToHeaderInvalidHttps) {
18334 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218335 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18336 RequestPolicy(cert_status);
Douglas Creager134b52e2018-11-09 18:00:1418337 histograms.ExpectBucketCount(
18338 ReportingHeaderParser::kHeaderOutcomeHistogram,
18339 ReportingHeaderParser::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR, 1);
18340}
18341#endif // BUILDFLAG(ENABLE_REPORTING)
18342
18343//-----------------------------------------------------------------------------
Douglas Creager3cb042052018-11-06 23:08:5218344// Network Error Logging tests
18345
18346#if BUILDFLAG(ENABLE_REPORTING)
Lily Chenfec60d92019-01-24 01:16:4218347namespace {
18348
18349const char kUserAgent[] = "Mozilla/1.0";
18350const char kReferrer[] = "https://www.referrer.org/";
18351
18352} // namespace
18353
Douglas Creager3cb042052018-11-06 23:08:5218354class HttpNetworkTransactionNetworkErrorLoggingTest
18355 : public HttpNetworkTransactionTest {
18356 protected:
18357 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618358 HttpNetworkTransactionTest::SetUp();
Douglas Creager3cb042052018-11-06 23:08:5218359 auto network_error_logging_service =
18360 std::make_unique<TestNetworkErrorLoggingService>();
18361 test_network_error_logging_service_ = network_error_logging_service.get();
18362 session_deps_.network_error_logging_service =
18363 std::move(network_error_logging_service);
Lily Chenfec60d92019-01-24 01:16:4218364
18365 extra_headers_.SetHeader("User-Agent", kUserAgent);
18366 extra_headers_.SetHeader("Referer", kReferrer);
18367
18368 request_.method = "GET";
18369 request_.url = GURL(url_);
18370 request_.extra_headers = extra_headers_;
18371 request_.reporting_upload_depth = reporting_upload_depth_;
18372 request_.traffic_annotation =
18373 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Douglas Creager3cb042052018-11-06 23:08:5218374 }
18375
18376 TestNetworkErrorLoggingService* network_error_logging_service() const {
18377 return test_network_error_logging_service_;
18378 }
18379
18380 void clear_network_error_logging_service() {
18381 session_deps_.network_error_logging_service.reset();
18382 test_network_error_logging_service_ = nullptr;
18383 }
18384
18385 // Makes an HTTPS request that should install a valid NEL policy.
Lily Chenfec60d92019-01-24 01:16:4218386 void RequestPolicy(CertStatus cert_status = 0) {
Douglas Creageref5eecdc2018-11-09 20:50:3618387 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318388 MockWrite data_writes[] = {
18389 MockWrite("GET / HTTP/1.1\r\n"
18390 "Host: www.example.org\r\n"
18391 "Connection: keep-alive\r\n"),
18392 MockWrite(ASYNC, extra_header_string.data(),
18393 extra_header_string.size()),
18394 };
Lily Chend3930e72019-03-01 19:31:1118395 MockRead data_reads[] = {
18396 MockRead("HTTP/1.0 200 OK\r\n"),
18397 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18398 MockRead("\r\n"),
18399 MockRead("hello world"),
18400 MockRead(SYNCHRONOUS, OK),
18401 };
Douglas Creager3cb042052018-11-06 23:08:5218402
Lily Chenfec60d92019-01-24 01:16:4218403 StaticSocketDataProvider reads(data_reads, data_writes);
18404 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager3cb042052018-11-06 23:08:5218405
18406 SSLSocketDataProvider ssl(ASYNC, OK);
Lily Chenfec60d92019-01-24 01:16:4218407 if (request_.url.SchemeIsCryptographic()) {
Douglas Creager3cb042052018-11-06 23:08:5218408 ssl.ssl_info.cert =
18409 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18410 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218411 ssl.ssl_info.cert_status = cert_status;
Douglas Creager3cb042052018-11-06 23:08:5218412 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18413 }
18414
Douglas Creager3cb042052018-11-06 23:08:5218415 TestCompletionCallback callback;
18416 auto session = CreateSession(&session_deps_);
18417 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
Lily Chenfec60d92019-01-24 01:16:4218418 int rv = trans.Start(&request_, callback.callback(), NetLogWithSource());
18419 EXPECT_THAT(callback.GetResult(rv), IsOk());
18420
18421 std::string response_data;
18422 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
18423 EXPECT_EQ("hello world", response_data);
18424 }
18425
18426 void CheckReport(size_t index,
18427 int status_code,
18428 int error_type,
18429 IPAddress server_ip = IPAddress::IPv4Localhost()) {
18430 ASSERT_LT(index, network_error_logging_service()->errors().size());
18431
18432 const NetworkErrorLoggingService::RequestDetails& error =
18433 network_error_logging_service()->errors()[index];
18434 EXPECT_EQ(url_, error.uri);
18435 EXPECT_EQ(kReferrer, error.referrer);
18436 EXPECT_EQ(kUserAgent, error.user_agent);
18437 EXPECT_EQ(server_ip, error.server_ip);
18438 EXPECT_EQ("http/1.1", error.protocol);
18439 EXPECT_EQ("GET", error.method);
18440 EXPECT_EQ(status_code, error.status_code);
18441 EXPECT_EQ(error_type, error.type);
18442 EXPECT_EQ(0, error.reporting_upload_depth);
Douglas Creager3cb042052018-11-06 23:08:5218443 }
18444
18445 protected:
18446 std::string url_ = "https://www.example.org/";
18447 CertStatus cert_status_ = 0;
Lily Chenfec60d92019-01-24 01:16:4218448 HttpRequestInfo request_;
Douglas Creageref5eecdc2018-11-09 20:50:3618449 HttpRequestHeaders extra_headers_;
18450 int reporting_upload_depth_ = 0;
Douglas Creager3cb042052018-11-06 23:08:5218451
18452 private:
18453 TestNetworkErrorLoggingService* test_network_error_logging_service_;
18454};
18455
18456TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18457 DontProcessNelHeaderNoService) {
18458 base::HistogramTester histograms;
18459 clear_network_error_logging_service();
18460 RequestPolicy();
18461 histograms.ExpectBucketCount(
18462 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18463 NetworkErrorLoggingService::HeaderOutcome::
18464 DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE,
18465 1);
18466}
18467
18468TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18469 DontProcessNelHeaderHttp) {
18470 base::HistogramTester histograms;
18471 url_ = "http://www.example.org/";
Lily Chenfec60d92019-01-24 01:16:4218472 request_.url = GURL(url_);
Douglas Creager3cb042052018-11-06 23:08:5218473 RequestPolicy();
18474 histograms.ExpectBucketCount(
18475 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18476 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18477}
18478
Lily Chen90ae93cc2019-02-14 01:15:3918479// Don't set NEL policies received on a proxied connection.
18480TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18481 DontProcessNelHeaderProxy) {
18482 session_deps_.proxy_resolution_service =
18483 ProxyResolutionService::CreateFixedFromPacResult(
18484 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
18485 BoundTestNetLog log;
18486 session_deps_.net_log = log.bound().net_log();
18487 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18488
18489 HttpRequestInfo request;
18490 request.method = "GET";
18491 request.url = GURL("https://www.example.org/");
18492 request.traffic_annotation =
18493 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18494
18495 // Since we have proxy, should try to establish tunnel.
18496 MockWrite data_writes1[] = {
18497 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
18498 "Host: www.example.org:443\r\n"
18499 "Proxy-Connection: keep-alive\r\n\r\n"),
18500
18501 MockWrite("GET / HTTP/1.1\r\n"
18502 "Host: www.example.org\r\n"
18503 "Connection: keep-alive\r\n\r\n"),
18504 };
18505
18506 MockRead data_reads1[] = {
18507 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
18508
18509 MockRead("HTTP/1.1 200 OK\r\n"),
18510 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18511 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18512 MockRead("Content-Length: 100\r\n\r\n"),
18513 MockRead(SYNCHRONOUS, OK),
18514 };
18515
18516 StaticSocketDataProvider data1(data_reads1, data_writes1);
18517 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18518 SSLSocketDataProvider ssl(ASYNC, OK);
18519 ssl.ssl_info.cert =
18520 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18521 ASSERT_TRUE(ssl.ssl_info.cert);
18522 ssl.ssl_info.cert_status = 0;
18523 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18524
18525 TestCompletionCallback callback1;
18526 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18527
18528 int rv = trans.Start(&request, callback1.callback(), log.bound());
18529 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18530
18531 rv = callback1.WaitForResult();
18532 EXPECT_THAT(rv, IsOk());
18533
18534 const HttpResponseInfo* response = trans.GetResponseInfo();
18535 ASSERT_TRUE(response);
18536 EXPECT_EQ(200, response->headers->response_code());
18537 EXPECT_TRUE(response->was_fetched_via_proxy);
18538
18539 // No NEL header was set.
18540 EXPECT_EQ(0u, network_error_logging_service()->headers().size());
18541}
18542
Douglas Creager3cb042052018-11-06 23:08:5218543TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) {
18544 RequestPolicy();
18545 ASSERT_EQ(1u, network_error_logging_service()->headers().size());
18546 const auto& header = network_error_logging_service()->headers()[0];
18547 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18548 header.origin);
18549 EXPECT_EQ(IPAddress::IPv4Localhost(), header.received_ip_address);
18550 EXPECT_EQ("{\"report_to\": \"nel\", \"max_age\": 86400}", header.value);
18551}
18552
18553TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18554 DontProcessNelHeaderInvalidHttps) {
18555 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218556 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18557 RequestPolicy(cert_status);
Douglas Creager3cb042052018-11-06 23:08:5218558 histograms.ExpectBucketCount(
18559 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18560 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR,
18561 1);
18562}
Douglas Creageref5eecdc2018-11-09 20:50:3618563
Lily Chenfec60d92019-01-24 01:16:4218564TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportSuccess) {
Douglas Creageref5eecdc2018-11-09 20:50:3618565 RequestPolicy();
18566 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4218567 CheckReport(0 /* index */, 200 /* status_code */, OK);
18568}
18569
18570TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18571 CreateReportErrorAfterStart) {
18572 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18573 auto trans =
18574 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18575
18576 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
18577 StaticSocketDataProvider data;
18578 data.set_connect_data(mock_connect);
18579 session_deps_.socket_factory->AddSocketDataProvider(&data);
18580
18581 TestCompletionCallback callback;
18582
18583 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18584 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18585
18586 trans.reset();
18587
18588 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18589 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18590 IPAddress() /* server_ip */);
18591}
18592
18593// Same as above except the error is ASYNC
18594TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18595 CreateReportErrorAfterStartAsync) {
18596 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18597 auto trans =
18598 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18599
18600 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
18601 StaticSocketDataProvider data;
18602 data.set_connect_data(mock_connect);
18603 session_deps_.socket_factory->AddSocketDataProvider(&data);
18604
18605 TestCompletionCallback callback;
18606
18607 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18608 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18609
18610 trans.reset();
18611
18612 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18613 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18614 IPAddress() /* server_ip */);
18615}
18616
18617TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18618 CreateReportReadBodyError) {
18619 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318620 MockWrite data_writes[] = {
18621 MockWrite("GET / HTTP/1.1\r\n"
18622 "Host: www.example.org\r\n"
18623 "Connection: keep-alive\r\n"),
18624 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18625 };
Lily Chend3930e72019-03-01 19:31:1118626 MockRead data_reads[] = {
18627 MockRead("HTTP/1.0 200 OK\r\n"),
18628 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18629 MockRead("hello world"),
18630 MockRead(SYNCHRONOUS, OK),
18631 };
Lily Chenfec60d92019-01-24 01:16:4218632
18633 StaticSocketDataProvider reads(data_reads, data_writes);
18634 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18635
18636 SSLSocketDataProvider ssl(ASYNC, OK);
18637 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18638
18639 // Log start time
18640 base::TimeTicks start_time = base::TimeTicks::Now();
18641
18642 TestCompletionCallback callback;
18643 auto session = CreateSession(&session_deps_);
18644 auto trans =
18645 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18646 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18647 EXPECT_THAT(callback.GetResult(rv), IsOk());
18648
18649 const HttpResponseInfo* response = trans->GetResponseInfo();
18650 ASSERT_TRUE(response);
18651
18652 EXPECT_TRUE(response->headers);
18653 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18654
18655 std::string response_data;
18656 rv = ReadTransaction(trans.get(), &response_data);
18657 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18658
18659 trans.reset();
18660
18661 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18662
18663 CheckReport(0 /* index */, 200 /* status_code */,
18664 ERR_CONTENT_LENGTH_MISMATCH);
18665 const NetworkErrorLoggingService::RequestDetails& error =
18666 network_error_logging_service()->errors()[0];
18667 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18668}
18669
18670// Same as above except the final read is ASYNC.
18671TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18672 CreateReportReadBodyErrorAsync) {
18673 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318674 MockWrite data_writes[] = {
18675 MockWrite("GET / HTTP/1.1\r\n"
18676 "Host: www.example.org\r\n"
18677 "Connection: keep-alive\r\n"),
18678 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18679 };
Lily Chend3930e72019-03-01 19:31:1118680 MockRead data_reads[] = {
18681 MockRead("HTTP/1.0 200 OK\r\n"),
18682 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18683 MockRead("hello world"),
18684 MockRead(ASYNC, OK),
18685 };
Lily Chenfec60d92019-01-24 01:16:4218686
18687 StaticSocketDataProvider reads(data_reads, data_writes);
18688 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18689
18690 SSLSocketDataProvider ssl(ASYNC, OK);
18691 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18692
18693 // Log start time
18694 base::TimeTicks start_time = base::TimeTicks::Now();
18695
18696 TestCompletionCallback callback;
18697 auto session = CreateSession(&session_deps_);
18698 auto trans =
18699 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18700 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18701 EXPECT_THAT(callback.GetResult(rv), IsOk());
18702
18703 const HttpResponseInfo* response = trans->GetResponseInfo();
18704 ASSERT_TRUE(response);
18705
18706 EXPECT_TRUE(response->headers);
18707 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18708
18709 std::string response_data;
18710 rv = ReadTransaction(trans.get(), &response_data);
18711 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18712
18713 trans.reset();
18714
18715 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18716
18717 CheckReport(0 /* index */, 200 /* status_code */,
18718 ERR_CONTENT_LENGTH_MISMATCH);
18719 const NetworkErrorLoggingService::RequestDetails& error =
18720 network_error_logging_service()->errors()[0];
18721 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18722}
18723
18724TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18725 CreateReportRestartWithAuth) {
18726 std::string extra_header_string = extra_headers_.ToString();
18727 static const base::TimeDelta kSleepDuration =
18728 base::TimeDelta::FromMilliseconds(10);
18729
18730 MockWrite data_writes1[] = {
18731 MockWrite("GET / HTTP/1.1\r\n"
18732 "Host: www.example.org\r\n"
18733 "Connection: keep-alive\r\n"),
18734 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18735 };
18736
18737 MockRead data_reads1[] = {
18738 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18739 // Give a couple authenticate options (only the middle one is actually
18740 // supported).
18741 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18742 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18743 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18744 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18745 // Large content-length -- won't matter, as connection will be reset.
18746 MockRead("Content-Length: 10000\r\n\r\n"),
18747 MockRead(SYNCHRONOUS, ERR_FAILED),
18748 };
18749
18750 // After calling trans->RestartWithAuth(), this is the request we should
18751 // be issuing -- the final header line contains the credentials.
18752 MockWrite data_writes2[] = {
18753 MockWrite("GET / HTTP/1.1\r\n"
18754 "Host: www.example.org\r\n"
18755 "Connection: keep-alive\r\n"
18756 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18757 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18758 };
18759
18760 // Lastly, the server responds with the actual content.
18761 MockRead data_reads2[] = {
18762 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18763 MockRead("hello world"),
18764 MockRead(SYNCHRONOUS, OK),
18765 };
18766
18767 StaticSocketDataProvider data1(data_reads1, data_writes1);
18768 StaticSocketDataProvider data2(data_reads2, data_writes2);
18769 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18770 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18771
18772 SSLSocketDataProvider ssl1(ASYNC, OK);
18773 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18774 SSLSocketDataProvider ssl2(ASYNC, OK);
18775 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18776
18777 base::TimeTicks start_time = base::TimeTicks::Now();
18778 base::TimeTicks restart_time;
18779
18780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18781 auto trans =
18782 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18783
18784 TestCompletionCallback callback1;
18785
18786 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18787 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18788
18789 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18790
18791 TestCompletionCallback callback2;
18792
18793 // Wait 10 ms then restart with auth
18794 FastForwardBy(kSleepDuration);
18795 restart_time = base::TimeTicks::Now();
18796 rv =
18797 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18798 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18799
18800 std::string response_data;
18801 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18802 EXPECT_EQ("hello world", response_data);
18803
18804 trans.reset();
18805
18806 // One 401 report for the auth challenge, then a 200 report for the successful
18807 // retry. Note that we don't report the error draining the body, as the first
18808 // request already generated a report for the auth challenge.
18809 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18810
18811 // Check error report contents
18812 CheckReport(0 /* index */, 401 /* status_code */, OK);
18813 CheckReport(1 /* index */, 200 /* status_code */, OK);
18814
18815 const NetworkErrorLoggingService::RequestDetails& error1 =
18816 network_error_logging_service()->errors()[0];
18817 const NetworkErrorLoggingService::RequestDetails& error2 =
18818 network_error_logging_service()->errors()[1];
18819
18820 // Sanity-check elapsed time values
18821 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18822 // Check that the start time is refreshed when restarting with auth.
18823 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18824}
18825
18826// Same as above, except draining the body before restarting fails
18827// asynchronously.
18828TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18829 CreateReportRestartWithAuthAsync) {
18830 std::string extra_header_string = extra_headers_.ToString();
18831 static const base::TimeDelta kSleepDuration =
18832 base::TimeDelta::FromMilliseconds(10);
18833
18834 MockWrite data_writes1[] = {
18835 MockWrite("GET / HTTP/1.1\r\n"
18836 "Host: www.example.org\r\n"
18837 "Connection: keep-alive\r\n"),
18838 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18839 };
18840
18841 MockRead data_reads1[] = {
18842 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18843 // Give a couple authenticate options (only the middle one is actually
18844 // supported).
18845 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18846 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18847 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18848 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18849 // Large content-length -- won't matter, as connection will be reset.
18850 MockRead("Content-Length: 10000\r\n\r\n"),
18851 MockRead(ASYNC, ERR_FAILED),
18852 };
18853
18854 // After calling trans->RestartWithAuth(), this is the request we should
18855 // be issuing -- the final header line contains the credentials.
18856 MockWrite data_writes2[] = {
18857 MockWrite("GET / HTTP/1.1\r\n"
18858 "Host: www.example.org\r\n"
18859 "Connection: keep-alive\r\n"
18860 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18861 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18862 };
18863
18864 // Lastly, the server responds with the actual content.
18865 MockRead data_reads2[] = {
18866 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18867 MockRead("hello world"),
18868 MockRead(SYNCHRONOUS, OK),
18869 };
18870
18871 StaticSocketDataProvider data1(data_reads1, data_writes1);
18872 StaticSocketDataProvider data2(data_reads2, data_writes2);
18873 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18874 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18875
18876 SSLSocketDataProvider ssl1(ASYNC, OK);
18877 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18878 SSLSocketDataProvider ssl2(ASYNC, OK);
18879 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18880
18881 base::TimeTicks start_time = base::TimeTicks::Now();
18882 base::TimeTicks restart_time;
18883
18884 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18885 auto trans =
18886 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18887
18888 TestCompletionCallback callback1;
18889
18890 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18891 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18892
18893 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18894
18895 TestCompletionCallback callback2;
18896
18897 // Wait 10 ms then restart with auth
18898 FastForwardBy(kSleepDuration);
18899 restart_time = base::TimeTicks::Now();
18900 rv =
18901 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18902 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18903
18904 std::string response_data;
18905 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18906 EXPECT_EQ("hello world", response_data);
18907
18908 trans.reset();
18909
18910 // One 401 report for the auth challenge, then a 200 report for the successful
18911 // retry. Note that we don't report the error draining the body, as the first
18912 // request already generated a report for the auth challenge.
18913 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18914
18915 // Check error report contents
18916 CheckReport(0 /* index */, 401 /* status_code */, OK);
18917 CheckReport(1 /* index */, 200 /* status_code */, OK);
18918
18919 const NetworkErrorLoggingService::RequestDetails& error1 =
18920 network_error_logging_service()->errors()[0];
18921 const NetworkErrorLoggingService::RequestDetails& error2 =
18922 network_error_logging_service()->errors()[1];
18923
18924 // Sanity-check elapsed time values
18925 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18926 // Check that the start time is refreshed when restarting with auth.
18927 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18928}
18929
18930TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18931 CreateReportRetryKeepAliveConnectionReset) {
18932 std::string extra_header_string = extra_headers_.ToString();
18933 MockWrite data_writes1[] = {
18934 MockWrite("GET / HTTP/1.1\r\n"
18935 "Host: www.example.org\r\n"
18936 "Connection: keep-alive\r\n"),
18937 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18938 MockWrite("GET / HTTP/1.1\r\n"
18939 "Host: www.example.org\r\n"
18940 "Connection: keep-alive\r\n"),
18941 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18942 };
18943
18944 MockRead data_reads1[] = {
18945 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18946 MockRead("hello"),
18947 // Connection is reset
18948 MockRead(ASYNC, ERR_CONNECTION_RESET),
18949 };
18950
18951 // Successful retry
18952 MockRead data_reads2[] = {
18953 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18954 MockRead("world"),
18955 MockRead(ASYNC, OK),
18956 };
18957
18958 StaticSocketDataProvider data1(data_reads1, data_writes1);
18959 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
18960 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18961 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18962
18963 SSLSocketDataProvider ssl1(ASYNC, OK);
18964 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18965 SSLSocketDataProvider ssl2(ASYNC, OK);
18966 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18967
18968 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18969 auto trans1 =
18970 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18971
18972 TestCompletionCallback callback1;
18973
18974 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
18975 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18976
18977 std::string response_data;
18978 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
18979 EXPECT_EQ("hello", response_data);
18980
18981 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18982
18983 auto trans2 =
18984 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18985
18986 TestCompletionCallback callback2;
18987
18988 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
18989 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18990
18991 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
18992 EXPECT_EQ("world", response_data);
18993
18994 trans1.reset();
18995 trans2.reset();
18996
18997 // One OK report from first request, then a ERR_CONNECTION_RESET report from
18998 // the second request, then an OK report from the successful retry.
18999 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19000
19001 // Check error report contents
19002 CheckReport(0 /* index */, 200 /* status_code */, OK);
19003 CheckReport(1 /* index */, 0 /* status_code */, ERR_CONNECTION_RESET);
19004 CheckReport(2 /* index */, 200 /* status_code */, OK);
19005}
19006
19007TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19008 CreateReportRetryKeepAlive408) {
19009 std::string extra_header_string = extra_headers_.ToString();
19010 MockWrite data_writes1[] = {
19011 MockWrite("GET / HTTP/1.1\r\n"
19012 "Host: www.example.org\r\n"
19013 "Connection: keep-alive\r\n"),
19014 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19015 MockWrite("GET / HTTP/1.1\r\n"
19016 "Host: www.example.org\r\n"
19017 "Connection: keep-alive\r\n"),
19018 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19019 };
19020
19021 MockRead data_reads1[] = {
19022 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19023 MockRead("hello"),
19024 // 408 Request Timeout
19025 MockRead(SYNCHRONOUS,
19026 "HTTP/1.1 408 Request Timeout\r\n"
19027 "Connection: Keep-Alive\r\n"
19028 "Content-Length: 6\r\n\r\n"
19029 "Pickle"),
19030 };
19031
19032 // Successful retry
19033 MockRead data_reads2[] = {
19034 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19035 MockRead("world"),
19036 MockRead(ASYNC, OK),
19037 };
19038
19039 StaticSocketDataProvider data1(data_reads1, data_writes1);
19040 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
19041 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19042 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19043
19044 SSLSocketDataProvider ssl1(ASYNC, OK);
19045 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
19046 SSLSocketDataProvider ssl2(ASYNC, OK);
19047 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
19048
19049 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19050 auto trans1 =
19051 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19052
19053 TestCompletionCallback callback1;
19054
19055 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
19056 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19057
19058 std::string response_data;
19059 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19060 EXPECT_EQ("hello", response_data);
19061
19062 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19063
19064 auto trans2 =
19065 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19066
19067 TestCompletionCallback callback2;
19068
19069 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
19070 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19071
19072 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19073 EXPECT_EQ("world", response_data);
19074
19075 trans1.reset();
19076 trans2.reset();
19077
19078 // One 200 report from first request, then a 408 report from
19079 // the second request, then a 200 report from the successful retry.
19080 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19081
19082 // Check error report contents
19083 CheckReport(0 /* index */, 200 /* status_code */, OK);
19084 CheckReport(1 /* index */, 408 /* status_code */, OK);
19085 CheckReport(2 /* index */, 200 /* status_code */, OK);
19086}
19087
19088TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19089 CreateReportRetry421WithoutConnectionPooling) {
19090 // Two hosts resolve to the same IP address.
19091 const std::string ip_addr = "1.2.3.4";
19092 IPAddress ip;
19093 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
19094 IPEndPoint peer_addr = IPEndPoint(ip, 443);
19095
19096 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
19097 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
19098 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
19099
19100 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19101
19102 // Two requests on the first connection.
19103 spdy::SpdySerializedFrame req1(
19104 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
19105 spdy_util_.UpdateWithStreamDestruction(1);
19106 spdy::SpdySerializedFrame req2(
19107 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
19108 spdy::SpdySerializedFrame rst(
19109 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
19110 MockWrite writes1[] = {
19111 CreateMockWrite(req1, 0),
19112 CreateMockWrite(req2, 3),
19113 CreateMockWrite(rst, 6),
19114 };
19115
19116 // The first one succeeds, the second gets error 421 Misdirected Request.
19117 spdy::SpdySerializedFrame resp1(
19118 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
19119 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
19120 spdy::SpdyHeaderBlock response_headers;
19121 response_headers[spdy::kHttp2StatusHeader] = "421";
19122 spdy::SpdySerializedFrame resp2(
19123 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
19124 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
19125 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
19126
19127 MockConnect connect1(ASYNC, OK, peer_addr);
19128 SequencedSocketData data1(connect1, reads1, writes1);
19129 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19130
19131 AddSSLSocketData();
19132
19133 // Retry the second request on a second connection.
19134 SpdyTestUtil spdy_util2;
19135 spdy::SpdySerializedFrame req3(
19136 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
19137 MockWrite writes2[] = {
19138 CreateMockWrite(req3, 0),
19139 };
19140
19141 spdy::SpdySerializedFrame resp3(
19142 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
19143 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
19144 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
19145 MockRead(ASYNC, 0, 3)};
19146
19147 MockConnect connect2(ASYNC, OK, peer_addr);
19148 SequencedSocketData data2(connect2, reads2, writes2);
19149 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19150
19151 AddSSLSocketData();
19152
19153 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3319154 int rv = session_deps_.host_resolver->LoadIntoCache(
19155 HostPortPair("mail.example.com", 443), base::nullopt);
19156 EXPECT_THAT(rv, IsOk());
Lily Chenfec60d92019-01-24 01:16:4219157
19158 HttpRequestInfo request1;
19159 request1.method = "GET";
19160 request1.url = GURL("https://www.example.org/");
19161 request1.load_flags = 0;
19162 request1.traffic_annotation =
19163 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19164 auto trans1 =
19165 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19166
Eric Orthf4db66a2019-02-19 21:35:3319167 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219168 rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
19169 EXPECT_THAT(callback.GetResult(rv), IsOk());
19170
19171 const HttpResponseInfo* response = trans1->GetResponseInfo();
19172 ASSERT_TRUE(response);
19173 ASSERT_TRUE(response->headers);
19174 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19175 EXPECT_TRUE(response->was_fetched_via_spdy);
19176 EXPECT_TRUE(response->was_alpn_negotiated);
19177 std::string response_data;
19178 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19179 EXPECT_EQ("hello!", response_data);
19180
19181 trans1.reset();
19182
19183 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19184
19185 HttpRequestInfo request2;
19186 request2.method = "GET";
19187 request2.url = GURL("https://mail.example.org/");
19188 request2.load_flags = 0;
19189 request2.traffic_annotation =
19190 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19191 auto trans2 =
19192 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19193
19194 BoundTestNetLog log;
19195 rv = trans2->Start(&request2, callback.callback(), log.bound());
19196 EXPECT_THAT(callback.GetResult(rv), IsOk());
19197
19198 response = trans2->GetResponseInfo();
19199 ASSERT_TRUE(response);
19200 ASSERT_TRUE(response->headers);
19201 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19202 EXPECT_TRUE(response->was_fetched_via_spdy);
19203 EXPECT_TRUE(response->was_alpn_negotiated);
19204 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19205 EXPECT_EQ("hello!", response_data);
19206
19207 trans2.reset();
19208
19209 // One 200 report from the first request, then a 421 report from the
19210 // second request, then a 200 report from the successful retry.
19211 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19212
19213 // Check error report contents
19214 const NetworkErrorLoggingService::RequestDetails& error1 =
19215 network_error_logging_service()->errors()[0];
19216 EXPECT_EQ(GURL("https://www.example.org/"), error1.uri);
19217 EXPECT_TRUE(error1.referrer.is_empty());
19218 EXPECT_EQ("", error1.user_agent);
19219 EXPECT_EQ(ip, error1.server_ip);
19220 EXPECT_EQ("h2", error1.protocol);
19221 EXPECT_EQ("GET", error1.method);
19222 EXPECT_EQ(200, error1.status_code);
19223 EXPECT_EQ(OK, error1.type);
19224 EXPECT_EQ(0, error1.reporting_upload_depth);
19225
19226 const NetworkErrorLoggingService::RequestDetails& error2 =
19227 network_error_logging_service()->errors()[1];
19228 EXPECT_EQ(GURL("https://mail.example.org/"), error2.uri);
19229 EXPECT_TRUE(error2.referrer.is_empty());
19230 EXPECT_EQ("", error2.user_agent);
19231 EXPECT_EQ(ip, error2.server_ip);
19232 EXPECT_EQ("h2", error2.protocol);
19233 EXPECT_EQ("GET", error2.method);
19234 EXPECT_EQ(421, error2.status_code);
19235 EXPECT_EQ(OK, error2.type);
19236 EXPECT_EQ(0, error2.reporting_upload_depth);
19237
19238 const NetworkErrorLoggingService::RequestDetails& error3 =
19239 network_error_logging_service()->errors()[2];
19240 EXPECT_EQ(GURL("https://mail.example.org/"), error3.uri);
19241 EXPECT_TRUE(error3.referrer.is_empty());
19242 EXPECT_EQ("", error3.user_agent);
19243 EXPECT_EQ(ip, error3.server_ip);
19244 EXPECT_EQ("h2", error3.protocol);
19245 EXPECT_EQ("GET", error3.method);
19246 EXPECT_EQ(200, error3.status_code);
19247 EXPECT_EQ(OK, error3.type);
19248 EXPECT_EQ(0, error3.reporting_upload_depth);
Douglas Creageref5eecdc2018-11-09 20:50:3619249}
19250
Lily Chend3930e72019-03-01 19:31:1119251TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19252 CreateReportCancelAfterStart) {
19253 StaticSocketDataProvider data;
19254 data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
19255 session_deps_.socket_factory->AddSocketDataProvider(&data);
19256
19257 TestCompletionCallback callback;
19258 auto session = CreateSession(&session_deps_);
19259 auto trans =
19260 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19261 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19262 EXPECT_EQ(rv, ERR_IO_PENDING);
19263
19264 // Cancel after start.
19265 trans.reset();
19266
19267 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19268 CheckReport(0 /* index */, 0 /* status_code */, ERR_ABORTED,
19269 IPAddress() /* server_ip */);
19270}
19271
19272TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19273 CreateReportCancelBeforeReadingBody) {
19274 std::string extra_header_string = extra_headers_.ToString();
19275 MockWrite data_writes[] = {
19276 MockWrite("GET / HTTP/1.1\r\n"
19277 "Host: www.example.org\r\n"
19278 "Connection: keep-alive\r\n"),
19279 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19280 };
19281 MockRead data_reads[] = {
19282 MockRead("HTTP/1.0 200 OK\r\n"),
19283 MockRead("Content-Length: 100\r\n\r\n"), // Body is never read.
19284 };
19285
19286 StaticSocketDataProvider data(data_reads, data_writes);
19287 session_deps_.socket_factory->AddSocketDataProvider(&data);
19288
19289 SSLSocketDataProvider ssl(ASYNC, OK);
19290 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19291
19292 TestCompletionCallback callback;
19293 auto session = CreateSession(&session_deps_);
19294 auto trans =
19295 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19296 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19297 EXPECT_THAT(callback.GetResult(rv), IsOk());
19298
19299 const HttpResponseInfo* response = trans->GetResponseInfo();
19300 ASSERT_TRUE(response);
19301
19302 EXPECT_TRUE(response->headers);
19303 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
19304
19305 // Cancel before reading the body.
19306 trans.reset();
19307
19308 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19309 CheckReport(0 /* index */, 200 /* status_code */, ERR_ABORTED);
19310}
19311
Lily Chen00196ab62018-12-04 19:52:2919312TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) {
19313 base::HistogramTester histograms;
19314 RequestPolicy();
19315 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19316 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19317
19318 // Make HTTP request
19319 std::string extra_header_string = extra_headers_.ToString();
19320 MockRead data_reads[] = {
19321 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
19322 MockRead("hello world"),
19323 MockRead(SYNCHRONOUS, OK),
19324 };
19325 MockWrite data_writes[] = {
19326 MockWrite("GET / HTTP/1.1\r\n"
19327 "Host: www.example.org\r\n"
19328 "Connection: keep-alive\r\n"),
19329 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19330 };
19331
Lily Chend3930e72019-03-01 19:31:1119332 StaticSocketDataProvider data(data_reads, data_writes);
19333 session_deps_.socket_factory->AddSocketDataProvider(&data);
Lily Chen00196ab62018-12-04 19:52:2919334
Lily Chenfec60d92019-01-24 01:16:4219335 // Insecure url
19336 url_ = "http://www.example.org/";
19337 request_.url = GURL(url_);
19338
Lily Chen00196ab62018-12-04 19:52:2919339 TestCompletionCallback callback;
19340 auto session = CreateSession(&session_deps_);
Lily Chenfec60d92019-01-24 01:16:4219341 auto trans =
19342 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19343 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19344 EXPECT_THAT(callback.GetResult(rv), IsOk());
19345
19346 std::string response_data;
19347 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19348 EXPECT_EQ("hello world", response_data);
Lily Chen00196ab62018-12-04 19:52:2919349
19350 // Insecure request does not generate a report
19351 histograms.ExpectBucketCount(
19352 NetworkErrorLoggingService::kRequestOutcomeHistogram,
Tsuyoshi Horo0b042232019-03-06 01:11:0519353 NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1);
Lily Chen00196ab62018-12-04 19:52:2919354
19355 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19356}
19357
19358TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19359 DontCreateReportHttpError) {
19360 base::HistogramTester histograms;
19361 RequestPolicy();
19362 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19363 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19364
19365 // Make HTTP request that fails
19366 MockRead data_reads[] = {
19367 MockRead("hello world"),
19368 MockRead(SYNCHRONOUS, OK),
19369 };
19370
19371 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
19372 session_deps_.socket_factory->AddSocketDataProvider(&data);
19373
Lily Chenfec60d92019-01-24 01:16:4219374 url_ = "http://www.originwithoutpolicy.com:2000/";
19375 request_.url = GURL(url_);
19376
Lily Chen00196ab62018-12-04 19:52:2919377 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19378
Lily Chen00196ab62018-12-04 19:52:2919379 auto trans =
19380 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Lily Chen00196ab62018-12-04 19:52:2919381 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219382 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
Lily Chen00196ab62018-12-04 19:52:2919383 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
19384
19385 // Insecure request does not generate a report, regardless of existence of a
19386 // policy for the origin.
19387 histograms.ExpectBucketCount(
19388 NetworkErrorLoggingService::kRequestOutcomeHistogram,
Tsuyoshi Horo0b042232019-03-06 01:11:0519389 NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1);
Lily Chen00196ab62018-12-04 19:52:2919390
19391 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19392}
19393
Lily Chen90ae93cc2019-02-14 01:15:3919394// Don't report on proxy auth challenges, don't report if connecting through a
19395// proxy.
19396TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportProxy) {
19397 HttpRequestInfo request;
19398 request.method = "GET";
19399 request.url = GURL("https://www.example.org/");
19400 request.traffic_annotation =
19401 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19402
19403 // Configure against proxy server "myproxy:70".
19404 session_deps_.proxy_resolution_service =
19405 ProxyResolutionService::CreateFixedFromPacResult(
19406 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
19407 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19408
19409 // Since we have proxy, should try to establish tunnel.
19410 MockWrite data_writes1[] = {
19411 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19412 "Host: www.example.org:443\r\n"
19413 "Proxy-Connection: keep-alive\r\n\r\n"),
19414 };
19415
19416 // The proxy responds to the connect with a 407, using a non-persistent
19417 // connection.
19418 MockRead data_reads1[] = {
19419 // No credentials.
19420 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
19421 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19422 MockRead("Proxy-Connection: close\r\n\r\n"),
19423 };
19424
19425 MockWrite data_writes2[] = {
19426 // After calling trans->RestartWithAuth(), this is the request we should
19427 // be issuing -- the final header line contains the credentials.
19428 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19429 "Host: www.example.org:443\r\n"
19430 "Proxy-Connection: keep-alive\r\n"
19431 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19432
19433 MockWrite("GET / HTTP/1.1\r\n"
19434 "Host: www.example.org\r\n"
19435 "Connection: keep-alive\r\n\r\n"),
19436 };
19437
19438 MockRead data_reads2[] = {
19439 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
19440
19441 MockRead("HTTP/1.1 200 OK\r\n"),
19442 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19443 MockRead("Content-Length: 5\r\n\r\n"),
19444 MockRead(SYNCHRONOUS, "hello"),
19445 };
19446
19447 StaticSocketDataProvider data1(data_reads1, data_writes1);
19448 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19449 StaticSocketDataProvider data2(data_reads2, data_writes2);
19450 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19451 SSLSocketDataProvider ssl(ASYNC, OK);
19452 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19453
19454 TestCompletionCallback callback1;
19455
19456 auto trans =
19457 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19458
19459 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
19460 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19461
19462 const HttpResponseInfo* response = trans->GetResponseInfo();
19463 EXPECT_EQ(407, response->headers->response_code());
19464
19465 std::string response_data;
19466 rv = ReadTransaction(trans.get(), &response_data);
19467 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
19468
19469 // No NEL report is generated for the 407.
19470 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19471
19472 TestCompletionCallback callback2;
19473
19474 rv =
19475 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
19476 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19477
19478 response = trans->GetResponseInfo();
19479 EXPECT_EQ(200, response->headers->response_code());
19480
19481 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19482 EXPECT_EQ("hello", response_data);
19483
19484 trans.reset();
19485
19486 // No NEL report is generated because we are behind a proxy.
19487 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19488}
19489
Douglas Creageref5eecdc2018-11-09 20:50:3619490TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19491 ReportContainsUploadDepth) {
19492 reporting_upload_depth_ = 7;
Lily Chenfec60d92019-01-24 01:16:4219493 request_.reporting_upload_depth = reporting_upload_depth_;
Douglas Creageref5eecdc2018-11-09 20:50:3619494 RequestPolicy();
19495 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219496 const NetworkErrorLoggingService::RequestDetails& error =
19497 network_error_logging_service()->errors()[0];
Douglas Creageref5eecdc2018-11-09 20:50:3619498 EXPECT_EQ(7, error.reporting_upload_depth);
19499}
19500
Lily Chenfec60d92019-01-24 01:16:4219501TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportElapsedTime) {
19502 std::string extra_header_string = extra_headers_.ToString();
19503 static const base::TimeDelta kSleepDuration =
19504 base::TimeDelta::FromMilliseconds(10);
19505
19506 std::vector<MockWrite> data_writes = {
19507 MockWrite(ASYNC, 0,
19508 "GET / HTTP/1.1\r\n"
19509 "Host: www.example.org\r\n"
19510 "Connection: keep-alive\r\n"),
19511 MockWrite(ASYNC, 1, extra_header_string.data()),
19512 };
19513
19514 std::vector<MockRead> data_reads = {
19515 // Write one byte of the status line, followed by a pause.
19516 MockRead(ASYNC, 2, "H"),
19517 MockRead(ASYNC, ERR_IO_PENDING, 3),
19518 MockRead(ASYNC, 4, "TTP/1.1 200 OK\r\n\r\n"),
19519 MockRead(ASYNC, 5, "hello world"),
19520 MockRead(SYNCHRONOUS, OK, 6),
19521 };
19522
19523 SequencedSocketData data(data_reads, data_writes);
19524 session_deps_.socket_factory->AddSocketDataProvider(&data);
19525
19526 SSLSocketDataProvider ssl(ASYNC, OK);
19527 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19528
19529 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19530
19531 auto trans =
19532 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19533
19534 TestCompletionCallback callback;
19535
19536 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19537 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19538
19539 data.RunUntilPaused();
19540 ASSERT_TRUE(data.IsPaused());
19541 FastForwardBy(kSleepDuration);
19542 data.Resume();
19543
19544 EXPECT_THAT(callback.GetResult(rv), IsOk());
19545
19546 std::string response_data;
19547 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19548 EXPECT_EQ("hello world", response_data);
19549
19550 trans.reset();
19551
Douglas Creageref5eecdc2018-11-09 20:50:3619552 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219553
19554 CheckReport(0 /* index */, 200 /* status_code */, OK);
19555
19556 const NetworkErrorLoggingService::RequestDetails& error =
19557 network_error_logging_service()->errors()[0];
19558
19559 // Sanity-check elapsed time in error report
19560 EXPECT_EQ(kSleepDuration, error.elapsed_time);
Douglas Creageref5eecdc2018-11-09 20:50:3619561}
Lily Chenfec60d92019-01-24 01:16:4219562
Douglas Creager3cb042052018-11-06 23:08:5219563#endif // BUILDFLAG(ENABLE_REPORTING)
19564
Batalov Vladislava4e97a502019-04-11 15:35:2319565TEST_F(HttpNetworkTransactionTest, AlwaysFailRequestToCache) {
19566 HttpRequestInfo request;
19567 request.method = "GET";
19568 request.url = GURL("http://example.org/");
19569
19570 request.load_flags = LOAD_ONLY_FROM_CACHE;
19571
19572 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19573 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19574 TestCompletionCallback callback1;
19575 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
19576
19577 EXPECT_THAT(rv, IsError(ERR_CACHE_MISS));
19578}
19579
Steven Valdez1c1859172019-04-10 15:33:2819580TEST_F(HttpNetworkTransactionTest, ZeroRTTDoesntConfirm) {
19581 HttpRequestInfo request;
19582 request.method = "GET";
19583 request.url = GURL("https://www.example.org/");
19584 request.traffic_annotation =
19585 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19586
19587 MockWrite data_writes[] = {
19588 MockWrite("GET / HTTP/1.1\r\n"
19589 "Host: www.example.org\r\n"
19590 "Connection: keep-alive\r\n\r\n"),
19591 };
19592
19593 // The proxy responds to the connect with a 407, using a persistent
19594 // connection.
19595 MockRead data_reads[] = {
19596 MockRead("HTTP/1.1 200 OK\r\n"),
19597 MockRead("Content-Length: 1\r\n\r\n"),
19598 MockRead(SYNCHRONOUS, "1"),
19599 };
19600
19601 StaticSocketDataProvider data(data_reads, data_writes);
19602 session_deps_.socket_factory->AddSocketDataProvider(&data);
19603 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19604 ssl.confirm = MockConfirm(SYNCHRONOUS, OK);
19605 session_deps_.enable_early_data = true;
19606 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19607
19608 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19609
19610 TestCompletionCallback callback;
19611 auto trans =
19612 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19613
19614 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19615 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19616
19617 rv = callback.WaitForResult();
19618 EXPECT_THAT(rv, IsOk());
19619
19620 const HttpResponseInfo* response = trans->GetResponseInfo();
19621 ASSERT_TRUE(response);
19622 ASSERT_TRUE(response->headers);
19623 EXPECT_EQ(200, response->headers->response_code());
19624 EXPECT_EQ(1, response->headers->GetContentLength());
19625
19626 // Check that ConfirmHandshake wasn't called.
19627 ASSERT_FALSE(ssl.ConfirmDataConsumed());
19628 ASSERT_TRUE(ssl.WriteBeforeConfirm());
19629
19630 trans.reset();
19631
19632 session->CloseAllConnections();
19633}
19634
19635TEST_F(HttpNetworkTransactionTest, ZeroRTTSyncConfirmSyncWrite) {
19636 HttpRequestInfo request;
19637 request.method = "POST";
19638 request.url = GURL("https://www.example.org/");
19639 request.traffic_annotation =
19640 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19641
19642 MockWrite data_writes[] = {
19643 MockWrite(SYNCHRONOUS,
19644 "POST / HTTP/1.1\r\n"
19645 "Host: www.example.org\r\n"
19646 "Connection: keep-alive\r\n"
19647 "Content-Length: 0\r\n\r\n"),
19648 };
19649
19650 // The proxy responds to the connect with a 407, using a persistent
19651 // connection.
19652 MockRead data_reads[] = {
19653 MockRead("HTTP/1.1 200 OK\r\n"),
19654 MockRead("Content-Length: 1\r\n\r\n"),
19655 MockRead(SYNCHRONOUS, "1"),
19656 };
19657
19658 StaticSocketDataProvider data(data_reads, data_writes);
19659 session_deps_.socket_factory->AddSocketDataProvider(&data);
19660 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19661 ssl.confirm = MockConfirm(SYNCHRONOUS, OK);
19662 session_deps_.enable_early_data = true;
19663 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19664
19665 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19666
19667 TestCompletionCallback callback;
19668 auto trans =
19669 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19670
19671 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19673
19674 rv = callback.WaitForResult();
19675 EXPECT_THAT(rv, IsOk());
19676
19677 const HttpResponseInfo* response = trans->GetResponseInfo();
19678 ASSERT_TRUE(response);
19679 ASSERT_TRUE(response->headers);
19680 EXPECT_EQ(200, response->headers->response_code());
19681 EXPECT_EQ(1, response->headers->GetContentLength());
19682
19683 // Check that the Write didn't get called before ConfirmHandshake completed.
19684 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19685
19686 trans.reset();
19687
19688 session->CloseAllConnections();
19689}
19690
19691TEST_F(HttpNetworkTransactionTest, ZeroRTTSyncConfirmAsyncWrite) {
19692 HttpRequestInfo request;
19693 request.method = "POST";
19694 request.url = GURL("https://www.example.org/");
19695 request.traffic_annotation =
19696 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19697
19698 MockWrite data_writes[] = {
19699 MockWrite(ASYNC,
19700 "POST / HTTP/1.1\r\n"
19701 "Host: www.example.org\r\n"
19702 "Connection: keep-alive\r\n"
19703 "Content-Length: 0\r\n\r\n"),
19704 };
19705
19706 // The proxy responds to the connect with a 407, using a persistent
19707 // connection.
19708 MockRead data_reads[] = {
19709 MockRead("HTTP/1.1 200 OK\r\n"),
19710 MockRead("Content-Length: 1\r\n\r\n"),
19711 MockRead(SYNCHRONOUS, "1"),
19712 };
19713
19714 StaticSocketDataProvider data(data_reads, data_writes);
19715 session_deps_.socket_factory->AddSocketDataProvider(&data);
19716 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19717 ssl.confirm = MockConfirm(SYNCHRONOUS, OK);
19718 session_deps_.enable_early_data = true;
19719 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19720
19721 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19722
19723 TestCompletionCallback callback;
19724 auto trans =
19725 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19726
19727 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19728 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19729
19730 rv = callback.WaitForResult();
19731 EXPECT_THAT(rv, IsOk());
19732
19733 const HttpResponseInfo* response = trans->GetResponseInfo();
19734 ASSERT_TRUE(response);
19735 ASSERT_TRUE(response->headers);
19736 EXPECT_EQ(200, response->headers->response_code());
19737 EXPECT_EQ(1, response->headers->GetContentLength());
19738
19739 // Check that the Write didn't get called before ConfirmHandshake completed.
19740 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19741
19742 trans.reset();
19743
19744 session->CloseAllConnections();
19745}
19746
19747TEST_F(HttpNetworkTransactionTest, ZeroRTTAsyncConfirmSyncWrite) {
19748 HttpRequestInfo request;
19749 request.method = "POST";
19750 request.url = GURL("https://www.example.org/");
19751 request.traffic_annotation =
19752 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19753
19754 MockWrite data_writes[] = {
19755 MockWrite(SYNCHRONOUS,
19756 "POST / HTTP/1.1\r\n"
19757 "Host: www.example.org\r\n"
19758 "Connection: keep-alive\r\n"
19759 "Content-Length: 0\r\n\r\n"),
19760 };
19761
19762 // The proxy responds to the connect with a 407, using a persistent
19763 // connection.
19764 MockRead data_reads[] = {
19765 MockRead("HTTP/1.1 200 OK\r\n"),
19766 MockRead("Content-Length: 1\r\n\r\n"),
19767 MockRead(SYNCHRONOUS, "1"),
19768 };
19769
19770 StaticSocketDataProvider data(data_reads, data_writes);
19771 session_deps_.socket_factory->AddSocketDataProvider(&data);
19772 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19773 ssl.confirm = MockConfirm(ASYNC, OK);
19774 session_deps_.enable_early_data = true;
19775 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19776
19777 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19778
19779 TestCompletionCallback callback;
19780 auto trans =
19781 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19782
19783 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19784 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19785
19786 rv = callback.WaitForResult();
19787 EXPECT_THAT(rv, IsOk());
19788
19789 const HttpResponseInfo* response = trans->GetResponseInfo();
19790 ASSERT_TRUE(response);
19791 ASSERT_TRUE(response->headers);
19792 EXPECT_EQ(200, response->headers->response_code());
19793 EXPECT_EQ(1, response->headers->GetContentLength());
19794
19795 // Check that the Write didn't get called before ConfirmHandshake completed.
19796 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19797
19798 trans.reset();
19799
19800 session->CloseAllConnections();
19801}
19802
19803TEST_F(HttpNetworkTransactionTest, ZeroRTTAsyncConfirmAsyncWrite) {
19804 HttpRequestInfo request;
19805 request.method = "POST";
19806 request.url = GURL("https://www.example.org/");
19807 request.traffic_annotation =
19808 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19809
19810 MockWrite data_writes[] = {
19811 MockWrite(ASYNC,
19812 "POST / HTTP/1.1\r\n"
19813 "Host: www.example.org\r\n"
19814 "Connection: keep-alive\r\n"
19815 "Content-Length: 0\r\n\r\n"),
19816 };
19817
19818 // The proxy responds to the connect with a 407, using a persistent
19819 // connection.
19820 MockRead data_reads[] = {
19821 MockRead("HTTP/1.1 200 OK\r\n"),
19822 MockRead("Content-Length: 1\r\n\r\n"),
19823 MockRead(SYNCHRONOUS, "1"),
19824 };
19825
19826 StaticSocketDataProvider data(data_reads, data_writes);
19827 session_deps_.socket_factory->AddSocketDataProvider(&data);
19828 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19829 ssl.confirm = MockConfirm(ASYNC, OK);
19830 session_deps_.enable_early_data = true;
19831 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19832
19833 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19834
19835 TestCompletionCallback callback;
19836 auto trans =
19837 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19838
19839 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19840 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19841
19842 rv = callback.WaitForResult();
19843 EXPECT_THAT(rv, IsOk());
19844
19845 const HttpResponseInfo* response = trans->GetResponseInfo();
19846 ASSERT_TRUE(response);
19847 ASSERT_TRUE(response->headers);
19848 EXPECT_EQ(200, response->headers->response_code());
19849 EXPECT_EQ(1, response->headers->GetContentLength());
19850
19851 // Check that the Write didn't get called before ConfirmHandshake completed.
19852 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19853
19854 trans.reset();
19855
19856 session->CloseAllConnections();
19857}
19858
19859TEST_F(HttpNetworkTransactionTest, ZeroRTTConfirmErrorSync) {
19860 HttpRequestInfo request;
19861 request.method = "POST";
19862 request.url = GURL("https://www.example.org/");
19863 request.traffic_annotation =
19864 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19865
19866 MockWrite data_writes[] = {
19867 MockWrite("POST / HTTP/1.1\r\n"
19868 "Host: www.example.org\r\n"
19869 "Connection: keep-alive\r\n"
19870 "Content-Length: 0\r\n\r\n"),
19871 };
19872
19873 // The proxy responds to the connect with a 407, using a persistent
19874 // connection.
19875 MockRead data_reads[] = {
19876 MockRead("HTTP/1.1 200 OK\r\n"),
19877 MockRead("Content-Length: 1\r\n\r\n"),
19878 MockRead(SYNCHRONOUS, "1"),
19879 };
19880
19881 StaticSocketDataProvider data(data_reads, data_writes);
19882 session_deps_.socket_factory->AddSocketDataProvider(&data);
19883 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19884 ssl.confirm = MockConfirm(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR);
19885 session_deps_.enable_early_data = true;
19886 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19887
19888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19889
19890 TestCompletionCallback callback;
19891 auto trans =
19892 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19893
19894 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19896
19897 rv = callback.WaitForResult();
19898 EXPECT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
19899
19900 // Check that the Write didn't get called before ConfirmHandshake completed.
19901 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19902
19903 trans.reset();
19904
19905 session->CloseAllConnections();
19906}
19907
19908TEST_F(HttpNetworkTransactionTest, ZeroRTTConfirmErrorAsync) {
19909 HttpRequestInfo request;
19910 request.method = "POST";
19911 request.url = GURL("https://www.example.org/");
19912 request.traffic_annotation =
19913 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19914
19915 MockWrite data_writes[] = {
19916 MockWrite("POST / HTTP/1.1\r\n"
19917 "Host: www.example.org\r\n"
19918 "Connection: keep-alive\r\n"
19919 "Content-Length: 0\r\n\r\n"),
19920 };
19921
19922 // The proxy responds to the connect with a 407, using a persistent
19923 // connection.
19924 MockRead data_reads[] = {
19925 MockRead("HTTP/1.1 200 OK\r\n"),
19926 MockRead("Content-Length: 1\r\n\r\n"),
19927 MockRead(SYNCHRONOUS, "1"),
19928 };
19929
19930 StaticSocketDataProvider data(data_reads, data_writes);
19931 session_deps_.socket_factory->AddSocketDataProvider(&data);
19932 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19933 ssl.confirm = MockConfirm(ASYNC, ERR_SSL_PROTOCOL_ERROR);
19934 session_deps_.enable_early_data = true;
19935 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19936
19937 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19938
19939 TestCompletionCallback callback;
19940 auto trans =
19941 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19942
19943 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19945
19946 rv = callback.WaitForResult();
19947 EXPECT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
19948
19949 // Check that the Write didn't get called before ConfirmHandshake completed.
19950 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19951
19952 trans.reset();
19953
19954 session->CloseAllConnections();
19955}
19956
[email protected]89ceba9a2009-03-21 03:46:0619957} // namespace net